about summary refs log tree commit diff
path: root/src/rt/sync
diff options
context:
space:
mode:
authorMichael Bebenita <mbebenita@mozilla.com>2010-09-09 16:01:49 -0700
committerMichael Bebenita <mbebenita@mozilla.com>2010-09-10 14:38:31 -0700
commitf985fded3ede8a7677ca6c9c77817d27bc9ae492 (patch)
treebf956b68b6b5dfd8744a1b14e55425fac5ce6c3b /src/rt/sync
parent79dc07d6487612ebf9ac62e43a5729ea774488b9 (diff)
Added lock_and_signal::signal_all(), and made the rust_kernel::join() use wait instead of yield.
Diffstat (limited to 'src/rt/sync')
-rwxr-xr-xsrc/rt/sync/lock_and_signal.cpp33
-rw-r--r--src/rt/sync/lock_and_signal.h1
2 files changed, 25 insertions, 9 deletions
diff --git a/src/rt/sync/lock_and_signal.cpp b/src/rt/sync/lock_and_signal.cpp
index c010086eb41..7a5d26fc6a9 100755
--- a/src/rt/sync/lock_and_signal.cpp
+++ b/src/rt/sync/lock_and_signal.cpp
@@ -11,7 +11,12 @@
 
 #if defined(__WIN32__)
 lock_and_signal::lock_and_signal() {
-    _event = CreateEvent(NULL, FALSE, FALSE, NULL);
+    // TODO: In order to match the behavior of pthread_cond_broadcast on
+    // Windows, we create manual reset events. This however breaks the
+    // behavior of pthread_cond_signal, fixing this is quite involved:
+    // refer to: http://www.cs.wustl.edu/~schmidt/win32-cv-1.html
+
+    _event = CreateEvent(NULL, TRUE, FALSE, NULL);
     InitializeCriticalSection(&_cs);
 }
 
@@ -33,21 +38,20 @@ lock_and_signal::~lock_and_signal() {
 
 void lock_and_signal::lock() {
 #if defined(__WIN32__)
-  EnterCriticalSection(&_cs);
+    EnterCriticalSection(&_cs);
 #else
-  pthread_mutex_lock(&_mutex);
+    pthread_mutex_lock(&_mutex);
 #endif
 }
 
 void lock_and_signal::unlock() {
 #if defined(__WIN32__)
-  LeaveCriticalSection(&_cs);
+    LeaveCriticalSection(&_cs);
 #else
-  pthread_mutex_unlock(&_mutex);
+    pthread_mutex_unlock(&_mutex);
 #endif
 }
 
-
 /**
  * Wait indefinitely until condition is signaled.
  */
@@ -57,9 +61,9 @@ void lock_and_signal::wait() {
 
 void lock_and_signal::timed_wait(size_t timeout_in_ns) {
 #if defined(__WIN32__)
-  LeaveCriticalSection(&_cs);
-  WaitForSingleObject(_event, INFINITE);
-  EnterCriticalSection(&_cs);
+    LeaveCriticalSection(&_cs);
+    WaitForSingleObject(_event, INFINITE);
+    EnterCriticalSection(&_cs);
 #else
     if (timeout_in_ns == 0) {
         pthread_cond_wait(&_cond, &_mutex);
@@ -85,6 +89,17 @@ void lock_and_signal::signal() {
 #endif
 }
 
+/**
+ * Signal condition, and resume all waiting threads.
+ */
+void lock_and_signal::signal_all() {
+#if defined(__WIN32__)
+    SetEvent(_event);
+#else
+    pthread_cond_broadcast(&_cond);
+#endif
+}
+
 
 //
 // Local Variables:
diff --git a/src/rt/sync/lock_and_signal.h b/src/rt/sync/lock_and_signal.h
index 5a852d9d026..1f1cfb4124b 100644
--- a/src/rt/sync/lock_and_signal.h
+++ b/src/rt/sync/lock_and_signal.h
@@ -18,6 +18,7 @@ public:
     void wait();
     void timed_wait(size_t timeout_in_ns);
     void signal();
+    void signal_all();
 };
 
 #endif /* LOCK_AND_SIGNAL_H */