diff options
| author | Eric Holk <eric.holk@gmail.com> | 2012-06-06 15:06:24 -0700 |
|---|---|---|
| committer | Eric Holk <eric.holk@gmail.com> | 2012-06-15 22:00:24 -0400 |
| commit | e394ebda37bf6bbe4c516e2b9381aac8bd964dcc (patch) | |
| tree | 58128171af062efa394ee0d0697bcb52c29bb21e /src/libcore | |
| parent | 5c9f414a85ae8f3448a27f56274afc861974cffe (diff) | |
| download | rust-e394ebda37bf6bbe4c516e2b9381aac8bd964dcc.tar.gz rust-e394ebda37bf6bbe4c516e2b9381aac8bd964dcc.zip | |
Adding a lock/condition variable to libcore.
Diffstat (limited to 'src/libcore')
| -rw-r--r-- | src/libcore/sys.rs | 72 |
1 files changed, 72 insertions, 0 deletions
diff --git a/src/libcore/sys.rs b/src/libcore/sys.rs index e0fd21f6c4a..90ea10601ae 100644 --- a/src/libcore/sys.rs +++ b/src/libcore/sys.rs @@ -7,6 +7,7 @@ export min_align_of; export pref_align_of; export refcount; export log_str; +export lock_and_signal, condition, methods; enum type_desc = { first_param: **libc::c_int, @@ -15,11 +16,20 @@ enum type_desc = { // Remaining fields not listed }; +type rust_cond_lock = *libc::c_void; + #[abi = "cdecl"] native mod rustrt { pure fn refcount(t: *()) -> libc::intptr_t; fn unsupervise(); pure fn shape_log_str(t: *sys::type_desc, data: *()) -> str; + + fn rust_create_cond_lock() -> rust_cond_lock; + fn rust_destroy_cond_lock(lock: rust_cond_lock); + fn rust_lock_cond_lock(lock: rust_cond_lock); + fn rust_unlock_cond_lock(lock: rust_cond_lock); + fn rust_wait_cond_lock(lock: rust_cond_lock); + fn rust_signal_cond_lock(lock: rust_cond_lock) -> bool; } #[abi = "rust-intrinsic"] @@ -74,8 +84,50 @@ pure fn log_str<T>(t: T) -> str { } } +resource lock_and_signal(lock: rust_cond_lock) { + rustrt::rust_destroy_cond_lock(lock); +} + +enum condition { + condition_(rust_cond_lock) +} + +resource unlock(lock: rust_cond_lock) { + rustrt::rust_unlock_cond_lock(lock); +} + +fn create_lock() -> lock_and_signal { + lock_and_signal(rustrt::rust_create_cond_lock()) +} + +impl methods for lock_and_signal { + fn lock<T>(f: fn() -> T) -> T { + rustrt::rust_lock_cond_lock(*self); + let _r = unlock(*self); + f() + } + + fn lock_cond<T>(f: fn(condition) -> T) -> T { + rustrt::rust_lock_cond_lock(*self); + let _r = unlock(*self); + f(condition_(*self)) + } +} + +impl methods for condition { + fn wait() { + rustrt::rust_wait_cond_lock(*self); + } + + fn signal() -> bool { + rustrt::rust_signal_cond_lock(*self) + } +} + #[cfg(test)] mod tests { + use std; + import std::arc; #[test] fn size_of_basic() { @@ -121,6 +173,26 @@ mod tests { assert pref_align_of::<uint>() == 8u; assert pref_align_of::<*uint>() == 8u; } + + #[test] + fn condition_variable() { + let lock = arc::arc(create_lock()); + let lock2 = arc::clone(&lock); + + task::spawn {|move lock2| + let lock = arc::get(&lock2); + (*lock).lock_cond {|c| + c.wait(); + } + } + + let mut signaled = false; + while !signaled { + (*arc::get(&lock)).lock_cond {|c| + signaled = c.signal() + } + } + } } // Local Variables: |
