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,
29 /// An RAII guard returned via `lock`
30 pub struct ExclusiveGuard<'a, T:'a> {
31 // FIXME #12808: strange name to try to avoid interfering with
32 // field accesses of the contained type via Deref
34 _guard: mutex::LockGuard<'a>,
37 impl<T: Send> Exclusive<T> {
38 /// Creates a new `Exclusive` which will protect the data provided.
39 pub fn new(user_data: T) -> Exclusive<T> {
41 lock: unsafe { mutex::NativeMutex::new() },
42 data: UnsafeCell::new(user_data),
46 /// Acquires this lock, returning a guard which the data is accessed through
47 /// and from which that lock will be unlocked.
49 /// This method is unsafe due to many of the same reasons that the
50 /// NativeMutex itself is unsafe.
51 pub unsafe fn lock<'a>(&'a self) -> ExclusiveGuard<'a, T> {
52 let guard = self.lock.lock();
53 let data = &mut *self.data.get();
62 impl<'a, T: Send> ExclusiveGuard<'a, T> {
63 // The unsafety here should be ok because our loan guarantees that the lock
64 // itself is not moving
65 pub fn signal(&self) {
66 unsafe { self._guard.signal() }
69 unsafe { self._guard.wait() }
73 impl<'a, T: Send> Deref<T> for ExclusiveGuard<'a, T> {
74 fn deref<'a>(&'a self) -> &'a T { &*self._data }
76 impl<'a, T: Send> DerefMut<T> for ExclusiveGuard<'a, T> {
77 fn deref_mut<'a>(&'a mut self) -> &'a mut T { &mut *self._data }
88 fn exclusive_new_arc() {
90 let mut futures = Vec::new();
95 let total = Arc::new(Exclusive::new(box 0));
97 for _ in range(0u, num_tasks) {
98 let total = total.clone();
99 let (tx, rx) = channel();
103 for _ in range(0u, count) {
110 for f in futures.mut_iter() { f.recv() }
112 assert_eq!(**total.lock(), num_tasks * count);