@@ -65,39 +65,36 @@ mod task_queue {
65
65
/// execution. The signal is sent once all TLS destructors have finished at
66
66
/// which point no new thread locals should be created.
67
67
pub mod wait_notify {
68
- use super :: super :: waitqueue:: { SpinMutex , WaitQueue , WaitVariable } ;
68
+ use super :: super :: thread_parker:: Parker ;
69
+ use crate :: pin:: Pin ;
69
70
use crate :: sync:: Arc ;
70
71
71
- pub struct Notifier ( Arc < SpinMutex < WaitVariable < bool > > > ) ;
72
+ pub struct Notifier ( Arc < Parker > ) ;
72
73
73
74
impl Notifier {
74
75
/// Notify the waiter. The waiter is either notified right away (if
75
76
/// currently blocked in `Waiter::wait()`) or later when it calls the
76
77
/// `Waiter::wait()` method.
77
78
pub fn notify ( self ) {
78
- let mut guard = self . 0 . lock ( ) ;
79
- * guard. lock_var_mut ( ) = true ;
80
- let _ = WaitQueue :: notify_one ( guard) ;
79
+ Pin :: new ( & * self . 0 ) . unpark ( )
81
80
}
82
81
}
83
82
84
- pub struct Waiter ( Arc < SpinMutex < WaitVariable < bool > > > ) ;
83
+ pub struct Waiter ( Arc < Parker > ) ;
85
84
86
85
impl Waiter {
87
86
/// Wait for a notification. If `Notifier::notify()` has already been
88
87
/// called, this will return immediately, otherwise the current thread
89
88
/// is blocked until notified.
90
89
pub fn wait ( self ) {
91
- let guard = self . 0 . lock ( ) ;
92
- if * guard. lock_var ( ) {
93
- return ;
94
- }
95
- WaitQueue :: wait ( guard, || { } ) ;
90
+ // This is not actually `unsafe`, but it uses the `Parker` API,
91
+ // which needs `unsafe` on some platforms.
92
+ unsafe { Pin :: new ( & * self . 0 ) . park ( ) }
96
93
}
97
94
}
98
95
99
96
pub fn new ( ) -> ( Notifier , Waiter ) {
100
- let inner = Arc :: new ( SpinMutex :: new ( WaitVariable :: new ( false ) ) ) ;
97
+ let inner = Arc :: new ( Parker :: new_internal ( ) ) ;
101
98
( Notifier ( inner. clone ( ) ) , Waiter ( inner) )
102
99
}
103
100
}
0 commit comments