1 // Copyright 2013 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
13 use core::cell::UnsafeCell;
16 /// An OS mutex over some data.
18 /// This is not a safe primitive to use, it is unaware of the libgreen
19 /// scheduler, as well as being easily susceptible to misuse due to the usage of
20 /// the inner NativeMutex.
22 /// > **Note**: This type is not recommended for general use. The mutex provided
23 /// > as part of `libsync` should almost always be favored.
24 pub struct Exclusive<T> {
25 lock: mutex::NativeMutex,
31 pub struct ExclusiveGuard<'a, T> {
32 // FIXME #12808: strange name to try to avoid interfering with
33 // field accesses of the contained type via Deref
35 _guard: mutex::LockGuard<'a>,
38 /// An RAII guard returned via `lock`
40 pub struct ExclusiveGuard<'a, T:'a> {
41 // FIXME #12808: strange name to try to avoid interfering with
42 // field accesses of the contained type via Deref
44 _guard: mutex::LockGuard<'a>,
47 impl<T: Send> Exclusive<T> {
48 /// Creates a new `Exclusive` which will protect the data provided.
49 pub fn new(user_data: T) -> Exclusive<T> {
51 lock: unsafe { mutex::NativeMutex::new() },
52 data: UnsafeCell::new(user_data),
56 /// Acquires this lock, returning a guard which the data is accessed through
57 /// and from which that lock will be unlocked.
59 /// This method is unsafe due to many of the same reasons that the
60 /// NativeMutex itself is unsafe.
61 pub unsafe fn lock<'a>(&'a self) -> ExclusiveGuard<'a, T> {
62 let guard = self.lock.lock();
63 let data = &mut *self.data.get();
72 impl<'a, T: Send> ExclusiveGuard<'a, T> {
73 // The unsafety here should be ok because our loan guarantees that the lock
74 // itself is not moving
75 pub fn signal(&self) {
76 unsafe { self._guard.signal() }
79 unsafe { self._guard.wait() }
83 impl<'a, T: Send> Deref<T> for ExclusiveGuard<'a, T> {
84 fn deref<'a>(&'a self) -> &'a T { &*self._data }
86 impl<'a, T: Send> DerefMut<T> for ExclusiveGuard<'a, T> {
87 fn deref_mut<'a>(&'a mut self) -> &'a mut T { &mut *self._data }
98 fn exclusive_new_arc() {
100 let mut futures = Vec::new();
105 let total = Arc::new(Exclusive::new(box 0));
107 for _ in range(0u, num_tasks) {
108 let total = total.clone();
109 let (tx, rx) = channel();
113 for _ in range(0u, count) {
120 for f in futures.mut_iter() { f.recv() }
122 assert_eq!(**total.lock(), num_tasks * count);