Commit f62a7c2d authored by Alex Crichton's avatar Alex Crichton

Tweak `get_type_slow` slightly

A few changes included in this small refactoring:

* The return value is asserted to not be `G_TYPE_INVALID`
* Instead of `catch_unwind` a `Drop` implementation is used.
* When spinning, use `yield_now` to ensure that not too much work is
  wasted

Closes #39
parent a889edbf
......@@ -386,23 +386,29 @@ impl<'lt, 'ast: 'lt, Boilerplate: boilerplate::Boilerplate<'ast>>
// 0 = unlocked, uninitialized
// 1 = locked while the GType is being computed
// anything else = unlocked, actual value of the GType
loop {
return loop {
match atype.compare_and_swap(0, 1, Ordering::SeqCst) {
0 => {
match ::std::panic::catch_unwind(get_type_inner) {
Ok(res) => {
atype.store(res, Ordering::SeqCst); //Make sure that priv-offset is set first
break res;
},
Err(err) => {
atype.store(0, Ordering::SeqCst); //Make sure that priv-offset is set first
::std::panic::resume_unwind(err)
}
}
let mut unlock = Unlock(true, atype);
let ty = get_type_inner();
assert!(ty != gobject_ffi::G_TYPE_INVALID);
unlock.0 = false;
atype.store(ty, Ordering::SeqCst);
break ty
},
1 => {},
1 => ::std::thread::yield_now(),
res => { break res }
}
};
struct Unlock<'a>(bool, &'a AtomicUsize);
impl<'a> Drop for Unlock<'a> {
fn drop(&mut self) {
if self.0 {
self.1.store(0, Ordering::SeqCst);
}
}
}
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment