about summary refs log tree commit diff
path: root/src/libstd/thread
diff options
context:
space:
mode:
authorJames Duley <james.duley@arm.com>2018-09-21 14:13:39 +0000
committerJames Duley <james.duley@arm.com>2018-10-30 22:54:35 +0000
commitd3e71e4986c3970d2f51b972c1dfdd740f89385a (patch)
tree015f2820023fbd47b658eb30850f42ca63c5cecb /src/libstd/thread
parente8aef7cae14bc7a56859408c90253e9bcc07fcff (diff)
downloadrust-d3e71e4986c3970d2f51b972c1dfdd740f89385a.tar.gz
rust-d3e71e4986c3970d2f51b972c1dfdd740f89385a.zip
thread::unpark: Avoid notifying with mutex locked.
This means when the other thread wakes it can continue right away
instead of having to wait for the mutex.

Also add some comments explaining why the mutex needs to be locked in
the first place.
Diffstat (limited to 'src/libstd/thread')
-rw-r--r--src/libstd/thread/mod.rs14
1 files changed, 12 insertions, 2 deletions
diff --git a/src/libstd/thread/mod.rs b/src/libstd/thread/mod.rs
index 3702c91966f..a57b8dc7237 100644
--- a/src/libstd/thread/mod.rs
+++ b/src/libstd/thread/mod.rs
@@ -1149,8 +1149,18 @@ impl Thread {
             _ => panic!("inconsistent state in unpark"),
         }
 
-        // Coordinate wakeup through the mutex and a condvar notification
-        let _lock = self.inner.lock.lock().unwrap();
+        // There is a period between when the parked thread sets `state` to
+        // `PARKED` (or last checked `state` in the case of a spurious wake
+        // up) and when it actually waits on `cvar`. If we were to notify
+        // during this period it would be ignored and then when the parked
+        // thread went to sleep it would never wake up. Fortunately, it has
+        // `lock` locked at this stage so we can acquire `lock` to wait until
+        // it is ready to receive the notification.
+        //
+        // Releasing `lock` before the call to `notify_one` means that when the
+        // parked thread wakes it doesn't get woken only to have to wait for us
+        // to release `lock`.
+        drop(self.inner.lock.lock().unwrap());
         self.inner.cvar.notify_one()
     }