Skip to content

add rust_trylock_little_lock #10428

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Nov 14, 2013
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 16 additions & 1 deletion src/libstd/unstable/sync.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
}
Expand Down Expand Up @@ -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);
Expand Down
5 changes: 5 additions & 0 deletions src/rt/rust_builtin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
1 change: 1 addition & 0 deletions src/rt/rustrt.def.in
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
26 changes: 26 additions & 0 deletions src/rt/sync/lock_and_signal.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How come this is explicitly checked?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

EBUSY is what happens when the lock is already locked.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm, I'd be more comfortable with a comment along the lines of:

// Explicitly return false on EBUSY (lock is already locked), but assert on all other errors

// 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)
Expand Down
1 change: 1 addition & 0 deletions src/rt/sync/lock_and_signal.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ class lock_and_signal {
virtual ~lock_and_signal();

void lock();
bool try_lock();
void unlock();
void wait();
void signal();
Expand Down