about summary refs log tree commit diff
path: root/src/libsync
diff options
context:
space:
mode:
authorAlex Crichton <alex@alexcrichton.com>2014-07-18 07:24:28 -0700
committerAlex Crichton <alex@alexcrichton.com>2014-07-18 07:26:55 -0700
commit3419e20f3b0800d40a4e33d47da7051d142e62ce (patch)
tree093da0d6f7dc5f9bd534ac34556e350a3ac078db /src/libsync
parent441866417764cb0ad32bce50ebda83deec525997 (diff)
downloadrust-3419e20f3b0800d40a4e33d47da7051d142e62ce.tar.gz
rust-3419e20f3b0800d40a4e33d47da7051d142e62ce.zip
sync: Fail with init semaphore count < 0
Semaphores are not currently designed to handle this case correctly, leading to
very strange behavior. Semaphores as written are intended to count *resources*
and it's not possible to have a negative number of resources.

This alters the behavior and documentation to note that the task will be failed
if the initial count is 0.

Closes #15758
Diffstat (limited to 'src/libsync')
-rw-r--r--src/libsync/raw.rs11
1 files changed, 11 insertions, 0 deletions
diff --git a/src/libsync/raw.rs b/src/libsync/raw.rs
index d056566bb9a..617943b2f93 100644
--- a/src/libsync/raw.rs
+++ b/src/libsync/raw.rs
@@ -109,6 +109,8 @@ struct SemGuard<'a, Q> {
 
 impl<Q: Send> Sem<Q> {
     fn new(count: int, q: Q) -> Sem<Q> {
+        assert!(count >= 0,
+                "semaphores cannot be initialized with negative values");
         Sem {
             lock: mutex::Mutex::new(),
             inner: Unsafe::new(SemInner {
@@ -364,6 +366,10 @@ pub struct SemaphoreGuard<'a> {
 
 impl Semaphore {
     /// Create a new semaphore with the specified count.
+    ///
+    /// # Failure
+    ///
+    /// This function will fail if `count` is negative.
     pub fn new(count: int) -> Semaphore {
         Semaphore { sem: Sem::new(count, ()) }
     }
@@ -637,6 +643,11 @@ mod tests {
         let _g = s.access();
     }
     #[test]
+    #[should_fail]
+    fn test_sem_basic2() {
+        Semaphore::new(-1);
+    }
+    #[test]
     fn test_sem_as_mutex() {
         let s = Arc::new(Semaphore::new(1));
         let s2 = s.clone();