about summary refs log tree commit diff
path: root/src/libsync
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2014-07-24 02:16:13 +0000
committerbors <bors@rust-lang.org>2014-07-24 02:16:13 +0000
commit221c28a08858f07cb3bb830834afd071fec840da (patch)
tree8357d28df633d217c1fd1ee72a1630c9277c335e /src/libsync
parent2224edcfe16ff798fcfa6f21a339822cb8b0f7ba (diff)
parent3419e20f3b0800d40a4e33d47da7051d142e62ce (diff)
downloadrust-221c28a08858f07cb3bb830834afd071fec840da.tar.gz
rust-221c28a08858f07cb3bb830834afd071fec840da.zip
auto merge of #15781 : alexcrichton/rust/issue-15758, r=bblum
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 1bdf24ea7dd..cb047798946 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();