auto merge of #10428 : toffaletti/rust/try_lock, r=alexcrichton
I need try_lock for an algorithm I'm trying to implement in Rust.
This commit is contained in:
commit
0d11935bf6
@ -13,7 +13,7 @@ use cell::Cell;
|
||||
use comm;
|
||||
use libc;
|
||||
use ptr;
|
||||
use option::*;
|
||||
use option::{Option,Some,None};
|
||||
use task;
|
||||
use unstable::atomics::{AtomicOption,AtomicUint,Acquire,Release,Relaxed,SeqCst};
|
||||
use unstable::finally::Finally;
|
||||
@ -354,6 +354,20 @@ impl LittleLock {
|
||||
}
|
||||
}
|
||||
|
||||
pub unsafe fn try_lock<T>(&self, f: &fn() -> T) -> Option<T> {
|
||||
do atomically {
|
||||
if rust_trylock_little_lock(self.l) {
|
||||
Some(do (|| {
|
||||
f()
|
||||
}).finally {
|
||||
rust_unlock_little_lock(self.l);
|
||||
})
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub unsafe fn signal(&self) {
|
||||
rust_signal_little_lock(self.l);
|
||||
}
|
||||
@ -478,6 +492,7 @@ impl<T:Send> Exclusive<T> {
|
||||
extern {
|
||||
fn rust_create_little_lock() -> rust_little_lock;
|
||||
fn rust_destroy_little_lock(lock: rust_little_lock);
|
||||
fn rust_trylock_little_lock(lock: rust_little_lock) -> bool;
|
||||
fn rust_lock_little_lock(lock: rust_little_lock);
|
||||
fn rust_unlock_little_lock(lock: rust_little_lock);
|
||||
fn rust_signal_little_lock(lock: rust_little_lock);
|
||||
|
@ -394,6 +394,11 @@ rust_lock_little_lock(lock_and_signal *lock) {
|
||||
lock->lock();
|
||||
}
|
||||
|
||||
extern "C" bool
|
||||
rust_trylock_little_lock(lock_and_signal *lock) {
|
||||
return lock->try_lock();
|
||||
}
|
||||
|
||||
extern "C" void
|
||||
rust_unlock_little_lock(lock_and_signal *lock) {
|
||||
lock->unlock();
|
||||
|
@ -37,6 +37,7 @@ rust_dbg_do_nothing
|
||||
rust_create_little_lock
|
||||
rust_destroy_little_lock
|
||||
rust_lock_little_lock
|
||||
rust_trylock_little_lock
|
||||
rust_unlock_little_lock
|
||||
rust_signal_little_lock
|
||||
rust_wait_little_lock
|
||||
|
@ -83,6 +83,32 @@ void lock_and_signal::lock() {
|
||||
#endif
|
||||
}
|
||||
|
||||
bool lock_and_signal::try_lock() {
|
||||
must_not_have_lock();
|
||||
#if defined(__WIN32__)
|
||||
if (TryEnterCriticalSection(&_cs)) {
|
||||
#if defined(DEBUG_LOCKS)
|
||||
_holding_thread = GetCurrentThreadId();
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
#else // non-windows
|
||||
int trylock = pthread_mutex_trylock(&_mutex);
|
||||
if (trylock == 0) {
|
||||
#if defined(DEBUG_LOCKS)
|
||||
_holding_thread = pthread_self();
|
||||
#endif
|
||||
return true;
|
||||
} else if (trylock == EBUSY) {
|
||||
// EBUSY means lock was already held by someone else
|
||||
return false;
|
||||
}
|
||||
// abort on all other errors
|
||||
CHECKED(trylock);
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
void lock_and_signal::unlock() {
|
||||
must_have_lock();
|
||||
#if defined(DEBUG_LOCKS)
|
||||
|
@ -43,6 +43,7 @@ public:
|
||||
virtual ~lock_and_signal();
|
||||
|
||||
void lock();
|
||||
bool try_lock();
|
||||
void unlock();
|
||||
void wait();
|
||||
void signal();
|
||||
|
Loading…
Reference in New Issue
Block a user