|
123 | 123 | //! * The `Thread::park()` function blocks the current thread unless or until
|
124 | 124 | //! the token is available for its thread handle, at which point It atomically
|
125 | 125 | //! consumes the token. It may also return *spuriously*, without consuming the
|
126 |
| -//! token. |
| 126 | +//! token. `Thread::park_timeout()` does the same, but allows specifying a |
| 127 | +//! maximum time to block the thread for. |
127 | 128 | //!
|
128 | 129 | //! * The `unpark()` method on a `Thread` atomically makes the token available
|
129 | 130 | //! if it wasn't already.
|
@@ -160,6 +161,7 @@ use string::String;
|
160 | 161 | use rt::{self, unwind};
|
161 | 162 | use old_io::{Writer, stdio};
|
162 | 163 | use thunk::Thunk;
|
| 164 | +use time::Duration; |
163 | 165 |
|
164 | 166 | use sys::thread as imp;
|
165 | 167 | use sys_common::{stack, thread_info};
|
@@ -414,6 +416,27 @@ impl Thread {
|
414 | 416 | *guard = false;
|
415 | 417 | }
|
416 | 418 |
|
| 419 | + /// Block unless or until the current thread's token is made available or |
| 420 | + /// the specified duration has been reached (may wake spuriously). |
| 421 | + /// |
| 422 | + /// The semantics of this function are equivalent to `park()` except that the |
| 423 | + /// thread will be blocked for roughly no longer than dur. This method |
| 424 | + /// should not be used for precise timing due to anomalies such as |
| 425 | + /// preemption or platform differences that may not cause the maximum |
| 426 | + /// amount of time waited to be precisely dur |
| 427 | + /// |
| 428 | + /// See the module doc for more detail. |
| 429 | + #[unstable(feature = "std_misc", reason = "recently introduced")] |
| 430 | + pub fn park_timeout(dur: Duration) { |
| 431 | + let thread = Thread::current(); |
| 432 | + let mut guard = thread.inner.lock.lock().unwrap(); |
| 433 | + if !*guard { |
| 434 | + let (g, _) = thread.inner.cvar.wait_timeout(guard, dur).unwrap(); |
| 435 | + guard = g; |
| 436 | + } |
| 437 | + *guard = false; |
| 438 | + } |
| 439 | + |
417 | 440 | /// Atomically makes the handle's token available if it is not already.
|
418 | 441 | ///
|
419 | 442 | /// See the module doc for more detail.
|
@@ -519,6 +542,7 @@ mod test {
|
519 | 542 | use std::old_io::{ChanReader, ChanWriter};
|
520 | 543 | use super::{Thread, Builder};
|
521 | 544 | use thunk::Thunk;
|
| 545 | + use time::Duration; |
522 | 546 |
|
523 | 547 | // !!! These tests are dangerous. If something is buggy, they will hang, !!!
|
524 | 548 | // !!! instead of exiting cleanly. This might wedge the buildbots. !!!
|
@@ -733,6 +757,37 @@ mod test {
|
733 | 757 | assert_eq!(output, "Hello, world!".to_string());
|
734 | 758 | }
|
735 | 759 |
|
| 760 | + #[test] |
| 761 | + fn test_park_timeout_unpark_before() { |
| 762 | + for _ in 0..10 { |
| 763 | + Thread::current().unpark(); |
| 764 | + Thread::park_timeout(Duration::seconds(10_000_000)); |
| 765 | + } |
| 766 | + } |
| 767 | + |
| 768 | + #[test] |
| 769 | + fn test_park_timeout_unpark_not_called() { |
| 770 | + for _ in 0..10 { |
| 771 | + Thread::park_timeout(Duration::milliseconds(10)); |
| 772 | + } |
| 773 | + } |
| 774 | + |
| 775 | + #[test] |
| 776 | + fn test_park_timeout_unpark_called_other_thread() { |
| 777 | + use std::old_io; |
| 778 | + |
| 779 | + for _ in 0..10 { |
| 780 | + let th = Thread::current(); |
| 781 | + |
| 782 | + let _guard = Thread::scoped(move || { |
| 783 | + old_io::timer::sleep(Duration::milliseconds(50)); |
| 784 | + th.unpark(); |
| 785 | + }); |
| 786 | + |
| 787 | + Thread::park_timeout(Duration::seconds(10_000_000)); |
| 788 | + } |
| 789 | + } |
| 790 | + |
736 | 791 | // NOTE: the corresponding test for stderr is in run-pass/task-stderr, due
|
737 | 792 | // to the test harness apparently interfering with stderr configuration.
|
738 | 793 | }
|
0 commit comments