about summary refs log tree commit diff
path: root/src/libstd/unstable/sync.rs
diff options
context:
space:
mode:
authorAlex Crichton <alex@alexcrichton.com>2013-10-22 15:00:37 -0700
committerAlex Crichton <alex@alexcrichton.com>2013-10-24 23:49:11 -0700
commit64a5c3bc1ee869990f8205374f9dac837a475dbd (patch)
treee791509c56fd43d8a5055e4d9ca163897ed4c4b5 /src/libstd/unstable/sync.rs
parent3ee5ef12fb71be95d6e7f679900a497a2580d25e (diff)
Implement a basic event loop built on LittleLock
It's not guaranteed that there will always be an event loop to run, and this
implementation will serve as an incredibly basic one which does not provide any
I/O, but allows the scheduler to still run.

cc #9128
Diffstat (limited to 'src/libstd/unstable/sync.rs')
-rw-r--r--src/libstd/unstable/sync.rs47
1 files changed, 47 insertions, 0 deletions
diff --git a/src/libstd/unstable/sync.rs b/src/libstd/unstable/sync.rs
index 9d15dd031e0..2b036c318ba 100644
--- a/src/libstd/unstable/sync.rs
+++ b/src/libstd/unstable/sync.rs
@@ -334,6 +334,23 @@ impl LittleLock {
             }
         }
     }
+
+    pub unsafe fn signal(&self) {
+        rust_signal_little_lock(self.l);
+    }
+
+    pub unsafe fn lock_and_wait(&self, f: &fn() -> bool) {
+        do atomically {
+            rust_lock_little_lock(self.l);
+            do (|| {
+                if f() {
+                    rust_wait_little_lock(self.l);
+                }
+            }).finally {
+                rust_unlock_little_lock(self.l);
+            }
+        }
+    }
 }
 
 struct ExData<T> {
@@ -402,6 +419,34 @@ impl<T:Send> Exclusive<T> {
         }
     }
 
+    #[inline]
+    pub unsafe fn hold_and_signal(&self, f: &fn(x: &mut T)) {
+        let rec = self.x.get();
+        do (*rec).lock.lock {
+            if (*rec).failed {
+                fail!("Poisoned Exclusive::new - another task failed inside!");
+            }
+            (*rec).failed = true;
+            f(&mut (*rec).data);
+            (*rec).failed = false;
+            (*rec).lock.signal();
+        }
+    }
+
+    #[inline]
+    pub unsafe fn hold_and_wait(&self, f: &fn(x: &T) -> bool) {
+        let rec = self.x.get();
+        do (*rec).lock.lock_and_wait {
+            if (*rec).failed {
+                fail!("Poisoned Exclusive::new - another task failed inside!");
+            }
+            (*rec).failed = true;
+            let result = f(&(*rec).data);
+            (*rec).failed = false;
+            result
+        }
+    }
+
     pub fn unwrap(self) -> T {
         let Exclusive { x: x } = self;
         // Someday we might need to unkillably unwrap an Exclusive, but not today.
@@ -415,6 +460,8 @@ externfn!(fn rust_create_little_lock() -> rust_little_lock)
 externfn!(fn rust_destroy_little_lock(lock: rust_little_lock))
 externfn!(fn rust_lock_little_lock(lock: rust_little_lock))
 externfn!(fn rust_unlock_little_lock(lock: rust_little_lock))
+externfn!(fn rust_signal_little_lock(lock: rust_little_lock))
+externfn!(fn rust_wait_little_lock(lock: rust_little_lock))
 
 #[cfg(test)]
 mod tests {