diff options
| author | Ben Blum <bblum@andrew.cmu.edu> | 2013-07-02 13:13:07 -0400 |
|---|---|---|
| committer | Ben Blum <bblum@andrew.cmu.edu> | 2013-07-20 05:08:55 -0400 |
| commit | 55adc4467b4364d949774d5bfd1eba4a16c0b810 (patch) | |
| tree | 7a029b032369c84298df542fda48108aab7dd972 /src/libstd | |
| parent | 28c9ba91d85e651ecf3568159bc3dfb45882baf8 (diff) | |
| download | rust-55adc4467b4364d949774d5bfd1eba4a16c0b810.tar.gz rust-55adc4467b4364d949774d5bfd1eba4a16c0b810.zip | |
Add AtomicOption::fill() and AtomicOption::is_empty()
Diffstat (limited to 'src/libstd')
| -rw-r--r-- | src/libstd/unstable/atomics.rs | 38 |
1 files changed, 38 insertions, 0 deletions
diff --git a/src/libstd/unstable/atomics.rs b/src/libstd/unstable/atomics.rs index 1e5ac305df3..dbb9c83ea39 100644 --- a/src/libstd/unstable/atomics.rs +++ b/src/libstd/unstable/atomics.rs @@ -272,6 +272,30 @@ impl<T> AtomicOption<T> { self.swap(cast::transmute(0), order) } } + + /// A compare-and-swap. Succeeds if the option is 'None' and returns 'None' + /// if so. If the option was already 'Some', returns 'Some' of the rejected + /// value. + #[inline] + pub fn fill(&mut self, val: ~T, order: Ordering) -> Option<~T> { + unsafe { + let val = cast::transmute(val); + let expected = cast::transmute(0); + let oldval = atomic_compare_and_swap(&mut self.p, expected, val, order); + if oldval == expected { + None + } else { + Some(cast::transmute(val)) + } + } + } + + /// Be careful: The caller must have some external method of ensuring the + /// result does not get invalidated by another task after this returns. + #[inline] + pub fn is_empty(&mut self, order: Ordering) -> bool { + unsafe { atomic_load(&self.p, order) == cast::transmute(0) } + } } #[unsafe_destructor] @@ -375,6 +399,11 @@ mod test { } #[test] + fn option_empty() { + assert!(AtomicOption::empty::<()>().is_empty(SeqCst)); + } + + #[test] fn option_swap() { let mut p = AtomicOption::new(~1); let a = ~2; @@ -398,4 +427,13 @@ mod test { assert_eq!(p.take(SeqCst), Some(~2)); } + #[test] + fn option_fill() { + let mut p = AtomicOption::new(~1); + assert!(p.fill(~2, SeqCst).is_some()); // should fail; shouldn't leak! + assert_eq!(p.take(SeqCst), Some(~1)); + + assert!(p.fill(~2, SeqCst).is_none()); // shouldn't fail + assert_eq!(p.take(SeqCst), Some(~2)); + } } |
