/// // critical section...
/// } // automatically unlocked in `_guard`'s destructor
/// ```
+ ///
+ /// # Unsafety
+ ///
+ /// This method is unsafe because it will not function correctly if this
+ /// mutex has been *moved* since it was last used. The mutex can move an
+ /// arbitrary number of times before its first usage, but once a mutex has
+ /// been used once it is no longer allowed to move (or otherwise it invokes
+ /// undefined behavior).
+ ///
+ /// Additionally, this type does not take into account any form of
+ /// scheduling model. This will unconditionally block the *os thread* which
+ /// is not always desired.
pub unsafe fn lock<'a>(&'a self) -> LockGuard<'a> {
self.inner.lock();
/// Attempts to acquire the lock. The value returned is `Some` if
/// the attempt succeeded.
+ ///
+ /// # Unsafety
+ ///
+ /// This method is unsafe for the same reasons as `lock`.
pub unsafe fn trylock<'a>(&'a self) -> Option<LockGuard<'a>> {
if self.inner.trylock() {
Some(LockGuard { lock: self })
///
/// These needs to be paired with a call to `.unlock_noguard`. Prefer using
/// `.lock`.
+ ///
+ /// # Unsafety
+ ///
+ /// This method is unsafe for the same reasons as `lock`. Additionally, this
+ /// does not guarantee that the mutex will ever be unlocked, and it is
+ /// undefined to drop an already-locked mutex.
pub unsafe fn lock_noguard(&self) { self.inner.lock() }
/// Attempts to acquire the lock without creating a
///
/// If `true` is returned, this needs to be paired with a call to
/// `.unlock_noguard`. Prefer using `.trylock`.
+ ///
+ /// # Unsafety
+ ///
+ /// This method is unsafe for the same reasons as `lock_noguard`.
pub unsafe fn trylock_noguard(&self) -> bool {
self.inner.trylock()
}
/// Unlocks the lock. This assumes that the current thread already holds the
/// lock.
+ ///
+ /// # Unsafety
+ ///
+ /// This method is unsafe for the same reasons as `lock`. Additionally, it
+ /// is not guaranteed that this is unlocking a previously locked mutex. It
+ /// is undefined to unlock an unlocked mutex.
pub unsafe fn unlock_noguard(&self) { self.inner.unlock() }
/// Block on the internal condition variable.
/// This function assumes that the lock is already held. Prefer
/// using `LockGuard.wait` since that guarantees that the lock is
/// held.
+ ///
+ /// # Unsafety
+ ///
+ /// This method is unsafe for the same reasons as `lock`. Additionally, this
+ /// is unsafe because the mutex may not be currently locked.
pub unsafe fn wait_noguard(&self) { self.inner.wait() }
/// Signals a thread in `wait` to wake up
+ ///
+ /// # Unsafety
+ ///
+ /// This method is unsafe for the same reasons as `lock`. Additionally, this
+ /// is unsafe because the mutex may not be currently locked.
pub unsafe fn signal_noguard(&self) { self.inner.signal() }
/// This function is especially unsafe because there are no guarantees made
/// already hold the lock.
///
/// # Example
+ ///
/// ```rust
/// use std::rt::mutex::NativeMutex;
/// unsafe {
/// } // automatically unlocked in `_guard`'s destructor
/// }
/// ```
+ ///
+ /// # Unsafety
+ ///
+ /// This method is unsafe due to the same reasons as
+ /// `StaticNativeMutex::lock`.
pub unsafe fn lock<'a>(&'a self) -> LockGuard<'a> {
self.inner.lock()
}
/// Attempts to acquire the lock. The value returned is `Some` if
/// the attempt succeeded.
+ ///
+ /// # Unsafety
+ ///
+ /// This method is unsafe due to the same reasons as
+ /// `StaticNativeMutex::trylock`.
pub unsafe fn trylock<'a>(&'a self) -> Option<LockGuard<'a>> {
self.inner.trylock()
}
///
/// These needs to be paired with a call to `.unlock_noguard`. Prefer using
/// `.lock`.
+ ///
+ /// # Unsafety
+ ///
+ /// This method is unsafe due to the same reasons as
+ /// `StaticNativeMutex::lock_noguard`.
pub unsafe fn lock_noguard(&self) { self.inner.lock_noguard() }
/// Attempts to acquire the lock without creating a
///
/// If `true` is returned, this needs to be paired with a call to
/// `.unlock_noguard`. Prefer using `.trylock`.
+ ///
+ /// # Unsafety
+ ///
+ /// This method is unsafe due to the same reasons as
+ /// `StaticNativeMutex::trylock_noguard`.
pub unsafe fn trylock_noguard(&self) -> bool {
self.inner.trylock_noguard()
}
/// Unlocks the lock. This assumes that the current thread already holds the
/// lock.
+ ///
+ /// # Unsafety
+ ///
+ /// This method is unsafe due to the same reasons as
+ /// `StaticNativeMutex::unlock_noguard`.
pub unsafe fn unlock_noguard(&self) { self.inner.unlock_noguard() }
/// Block on the internal condition variable.
/// This function assumes that the lock is already held. Prefer
/// using `LockGuard.wait` since that guarantees that the lock is
/// held.
+ ///
+ /// # Unsafety
+ ///
+ /// This method is unsafe due to the same reasons as
+ /// `StaticNativeMutex::wait_noguard`.
pub unsafe fn wait_noguard(&self) { self.inner.wait_noguard() }
/// Signals a thread in `wait` to wake up
+ ///
+ /// # Unsafety
+ ///
+ /// This method is unsafe due to the same reasons as
+ /// `StaticNativeMutex::signal_noguard`.
pub unsafe fn signal_noguard(&self) { self.inner.signal_noguard() }
}
use libc;
use self::os::{PTHREAD_MUTEX_INITIALIZER, PTHREAD_COND_INITIALIZER,
pthread_mutex_t, pthread_cond_t};
- use core::ty::Unsafe;
- use core::kinds::marker;
+ use core::cell::UnsafeCell;
type pthread_mutexattr_t = libc::c_void;
type pthread_condattr_t = libc::c_void;
#[cfg(target_os = "freebsd")]
+ #[cfg(target_os = "dragonfly")]
mod os {
use libc;
- pub type pthread_mutex_t = *libc::c_void;
- pub type pthread_cond_t = *libc::c_void;
+ pub type pthread_mutex_t = *mut libc::c_void;
+ pub type pthread_cond_t = *mut libc::c_void;
pub static PTHREAD_MUTEX_INITIALIZER: pthread_mutex_t =
0 as pthread_mutex_t;
}
#[cfg(target_os = "macos")]
+ #[cfg(target_os = "ios")]
mod os {
use libc;
static __PTHREAD_MUTEX_SIZE__: uint = 40;
#[cfg(target_arch = "x86")]
static __PTHREAD_COND_SIZE__: uint = 24;
+ #[cfg(target_arch = "arm")]
+ static __PTHREAD_MUTEX_SIZE__: uint = 40;
+ #[cfg(target_arch = "arm")]
+ static __PTHREAD_COND_SIZE__: uint = 24;
static _PTHREAD_MUTEX_SIG_init: libc::c_long = 0x32AAABA7;
static _PTHREAD_COND_SIG_init: libc::c_long = 0x3CB0B1BB;
static __SIZEOF_PTHREAD_MUTEX_T: uint = 24 - 8;
#[cfg(target_arch = "mips")]
static __SIZEOF_PTHREAD_MUTEX_T: uint = 24 - 8;
+ #[cfg(target_arch = "mipsel")]
+ static __SIZEOF_PTHREAD_MUTEX_T: uint = 24 - 8;
#[cfg(target_arch = "x86_64")]
static __SIZEOF_PTHREAD_COND_T: uint = 48 - 8;
#[cfg(target_arch = "x86")]
static __SIZEOF_PTHREAD_COND_T: uint = 48 - 8;
#[cfg(target_arch = "mips")]
static __SIZEOF_PTHREAD_COND_T: uint = 48 - 8;
+ #[cfg(target_arch = "mipsel")]
+ static __SIZEOF_PTHREAD_COND_T: uint = 48 - 8;
#[repr(C)]
pub struct pthread_mutex_t {
}
pub struct Mutex {
- lock: Unsafe<pthread_mutex_t>,
- cond: Unsafe<pthread_cond_t>,
+ lock: UnsafeCell<pthread_mutex_t>,
+ cond: UnsafeCell<pthread_cond_t>,
}
pub static MUTEX_INIT: Mutex = Mutex {
- lock: Unsafe {
- value: PTHREAD_MUTEX_INITIALIZER,
- marker1: marker::InvariantType,
- },
- cond: Unsafe {
- value: PTHREAD_COND_INITIALIZER,
- marker1: marker::InvariantType,
- },
+ lock: UnsafeCell { value: PTHREAD_MUTEX_INITIALIZER },
+ cond: UnsafeCell { value: PTHREAD_COND_INITIALIZER },
};
impl Mutex {
// is better to avoid initialization of potentially
// opaque OS data before it landed
let m = Mutex {
- lock: Unsafe::new(PTHREAD_MUTEX_INITIALIZER),
- cond: Unsafe::new(PTHREAD_COND_INITIALIZER),
+ lock: UnsafeCell::new(PTHREAD_MUTEX_INITIALIZER),
+ cond: UnsafeCell::new(PTHREAD_COND_INITIALIZER),
};
return m;