about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2013-11-14 11:51:25 -0800
committerbors <bors@rust-lang.org>2013-11-14 11:51:25 -0800
commit0d11935bf6ae3e784aefb1c359a70fea5dfd3d00 (patch)
tree6b4dd24f9c57a550f059e3f9d058ac9be7f9286f /src
parent11ece44f02fdedb79a51b8100d36c84ee4c9408f (diff)
parent91de538c9802e7c45cadc5391450631c74f593d2 (diff)
downloadrust-0d11935bf6ae3e784aefb1c359a70fea5dfd3d00.tar.gz
rust-0d11935bf6ae3e784aefb1c359a70fea5dfd3d00.zip
auto merge of #10428 : toffaletti/rust/try_lock, r=alexcrichton
I need try_lock for an algorithm I'm trying to implement in Rust.
Diffstat (limited to 'src')
-rw-r--r--src/libstd/unstable/sync.rs17
-rw-r--r--src/rt/rust_builtin.cpp5
-rw-r--r--src/rt/rustrt.def.in1
-rw-r--r--src/rt/sync/lock_and_signal.cpp26
-rw-r--r--src/rt/sync/lock_and_signal.h1
5 files changed, 49 insertions, 1 deletions
diff --git a/src/libstd/unstable/sync.rs b/src/libstd/unstable/sync.rs
index a08b914ca31..0e1f5fc1bdc 100644
--- a/src/libstd/unstable/sync.rs
+++ b/src/libstd/unstable/sync.rs
@@ -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);
diff --git a/src/rt/rust_builtin.cpp b/src/rt/rust_builtin.cpp
index 90042491d1d..4c1c6a7202a 100644
--- a/src/rt/rust_builtin.cpp
+++ b/src/rt/rust_builtin.cpp
@@ -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();
diff --git a/src/rt/rustrt.def.in b/src/rt/rustrt.def.in
index 3b581e94be7..1f440047d4e 100644
--- a/src/rt/rustrt.def.in
+++ b/src/rt/rustrt.def.in
@@ -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
diff --git a/src/rt/sync/lock_and_signal.cpp b/src/rt/sync/lock_and_signal.cpp
index 3d7ad02c438..fcf8ab5d88b 100644
--- a/src/rt/sync/lock_and_signal.cpp
+++ b/src/rt/sync/lock_and_signal.cpp
@@ -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)
diff --git a/src/rt/sync/lock_and_signal.h b/src/rt/sync/lock_and_signal.h
index 5a0eb83a394..45e1f719851 100644
--- a/src/rt/sync/lock_and_signal.h
+++ b/src/rt/sync/lock_and_signal.h
@@ -43,6 +43,7 @@ public:
     virtual ~lock_and_signal();
 
     void lock();
+    bool try_lock();
     void unlock();
     void wait();
     void signal();