use boxed::Box;
use cell::UnsafeCell;
use clone::Clone;
-use kinds::Send;
+use kinds::{Send, Sync};
use ops::{Drop, FnOnce};
use option::Option::{mod, Some, None};
use result::Result::{Err, Ok};
}
fn spawn_inner<T: Send>(self, f: Thunk<(), T>) -> JoinGuard<T> {
- let my_packet = Arc::new(UnsafeCell::new(None));
- let their_packet = my_packet.clone();
+ let my_packet = Packet(Arc::new(UnsafeCell::new(None)));
+ let their_packet = Packet(my_packet.0.clone());
let Builder { name, stack_size, stdout, stderr } = self;
}
};
unsafe {
- *their_packet.get() = Some(match (output, try_result) {
+ *their_packet.0.get() = Some(match (output, try_result) {
(Some(data), Ok(_)) => Ok(data),
(None, Err(cause)) => Err(cause),
_ => unreachable!()
cvar: Condvar,
}
+unsafe impl Sync for Inner {}
+
#[deriving(Clone)]
/// A handle to a thread.
pub struct Thread {
inner: Arc<Inner>,
}
+unsafe impl Sync for Thread {}
+
impl Thread {
// Used only internally to construct a thread object without spawning
fn new(name: Option<String>) -> Thread {
}
/// Determines whether the current thread is panicking.
+ #[inline]
pub fn panicking() -> bool {
unwind::panicking()
}
// or futuxes, and in either case may allow spurious wakeups.
pub fn park() {
let thread = Thread::current();
- let mut guard = thread.inner.lock.lock();
+ let mut guard = thread.inner.lock.lock().unwrap();
while !*guard {
- thread.inner.cvar.wait(&guard);
+ guard = thread.inner.cvar.wait(guard).unwrap();
}
*guard = false;
}
///
/// See the module doc for more detail.
pub fn unpark(&self) {
- let mut guard = self.inner.lock.lock();
+ let mut guard = self.inner.lock.lock().unwrap();
if !*guard {
*guard = true;
self.inner.cvar.notify_one();
/// A thread that completes without panicking is considered to exit successfully.
pub type Result<T> = ::result::Result<T, Box<Any + Send>>;
+struct Packet<T>(Arc<UnsafeCell<Option<Result<T>>>>);
+
+unsafe impl<T:'static+Send> Send for Packet<T> {}
+unsafe impl<T> Sync for Packet<T> {}
+
#[must_use]
/// An RAII-style guard that will block until thread termination when dropped.
///
native: imp::rust_thread,
thread: Thread,
joined: bool,
- packet: Arc<UnsafeCell<Option<Result<T>>>>,
+ packet: Packet<T>,
}
+unsafe impl<T: Send> Sync for JoinGuard<T> {}
+
impl<T: Send> JoinGuard<T> {
/// Extract a handle to the thread this guard will join on.
pub fn thread(&self) -> &Thread {
unsafe { imp::join(self.native) };
self.joined = true;
unsafe {
- (*self.packet.get()).take().unwrap()
+ (*self.packet.0.get()).take().unwrap()
}
}