]> git.lizzy.rs Git - rust.git/commitdiff
Add failing tests for mutex and rwlock
authorDavid Cook <divergentdave@gmail.com>
Tue, 28 Jan 2020 03:49:06 +0000 (21:49 -0600)
committerDavid Cook <divergentdave@gmail.com>
Sun, 5 Apr 2020 14:25:21 +0000 (09:25 -0500)
src/shims/foreign_items/posix.rs
tests/run-pass/sync.rs

index 4be63804a45b7dbea122845b5ec17a882aa4ac0f..061ae93d8f675f29a8445d1a04ddbba78ba3c94a 100644 (file)
@@ -268,6 +268,7 @@ fn emulate_foreign_item_by_name(
             | "pthread_mutex_init"
             | "pthread_mutexattr_destroy"
             | "pthread_mutex_lock"
+            | "pthread_mutex_trylock"
             | "pthread_mutex_unlock"
             | "pthread_mutex_destroy"
             | "pthread_rwlock_rdlock"
index 14243349f967115cc08c139bbbd458ffaffebe8f..6a0b41d5f6a7902c948797e581ec7fc439475fad 100644 (file)
@@ -1,20 +1,81 @@
 // Just instantiate some data structures to make sure we got all their foreign items covered.
 // Requires full MIR on Windows.
 
+#![feature(rustc_private)]
+
 use std::sync;
 
+extern crate libc;
+
 fn main() {
     let m = sync::Mutex::new(0);
-    drop(m.lock());
+    {
+        let _guard = m.lock();
+        let try_lock_error = m.try_lock().unwrap_err();
+        if let sync::TryLockError::Poisoned(e) = try_lock_error {
+            panic!("{}", e);
+        }
+    }
+    drop(m.try_lock().unwrap());
     drop(m);
 
     #[cfg(not(target_os = "windows"))] // TODO: implement RwLock on Windows
     {
         let rw = sync::RwLock::new(0);
-        drop(rw.read());
-        drop(rw.try_read());
-        drop(rw.write());
-        drop(rw.try_write());
-        drop(rw);
+        {
+            let _read_guard = rw.read().unwrap();
+            drop(rw.read().unwrap());
+            drop(rw.try_read().unwrap());
+            let try_lock_error = rw.try_write().unwrap_err();
+            if let sync::TryLockError::Poisoned(e) = try_lock_error {
+                panic!("{}", e);
+            }
+        }
+
+        {
+            let _write_guard = rw.write().unwrap();
+            let try_lock_error = rw.try_read().unwrap_err();
+            if let sync::TryLockError::Poisoned(e) = try_lock_error {
+                panic!("{}", e);
+            }
+            let try_lock_error = rw.try_write().unwrap_err();
+            if let sync::TryLockError::Poisoned(e) = try_lock_error {
+                panic!("{}", e);
+            }
+        }
+
+        // need to go a layer deeper and test the behavior of libc functions, because
+        // std::sys::unix::rwlock::RWLock keeps track of write_locked and num_readers
+
+        unsafe {
+            let mut mutex: libc::pthread_mutex_t = std::mem::zeroed();
+            assert_eq!(libc::pthread_mutex_init(&mut mutex as *mut _, std::ptr::null_mut()), 0);
+            assert_eq!(libc::pthread_mutex_lock(&mut mutex as *mut _), 0);
+            assert_eq!(libc::pthread_mutex_trylock(&mut mutex as *mut _), libc::EBUSY);
+            assert_eq!(libc::pthread_mutex_unlock(&mut mutex as *mut _), 0);
+            assert_eq!(libc::pthread_mutex_trylock(&mut mutex as *mut _), 0);
+            assert_eq!(libc::pthread_mutex_unlock(&mut mutex as *mut _), 0);
+            assert_eq!(libc::pthread_mutex_destroy(&mut mutex as *mut _), 0);
+        }
+
+        unsafe {
+            let mut rw: libc::pthread_rwlock_t = std::mem::zeroed();
+            assert_eq!(libc::pthread_rwlock_init(&mut rw as *mut _, std::ptr::null_mut()), 0);
+
+            assert_eq!(libc::pthread_rwlock_rdlock(&mut rw as *mut _), 0);
+            assert_eq!(libc::pthread_rwlock_rdlock(&mut rw as *mut _), 0);
+            assert_eq!(libc::pthread_rwlock_unlock(&mut rw as *mut _), 0);
+            assert_eq!(libc::pthread_rwlock_tryrdlock(&mut rw as *mut _), 0);
+            assert_eq!(libc::pthread_rwlock_unlock(&mut rw as *mut _), 0);
+            assert_eq!(libc::pthread_rwlock_trywrlock(&mut rw as *mut _), libc::EBUSY);
+            assert_eq!(libc::pthread_rwlock_unlock(&mut rw as *mut _), 0);
+
+            assert_eq!(libc::pthread_rwlock_wrlock(&mut rw as *mut _), 0);
+            assert_eq!(libc::pthread_rwlock_tryrdlock(&mut rw as *mut _), libc::EBUSY);
+            assert_eq!(libc::pthread_rwlock_trywrlock(&mut rw as *mut _), libc::EBUSY);
+            assert_eq!(libc::pthread_rwlock_unlock(&mut rw as *mut _), 0);
+
+            assert_eq!(libc::pthread_rwlock_destroy(&mut rw as *mut _), 0);
+        }
     }
 }