@@ -2,31 +2,25 @@ use crate::cell::UnsafeCell;
2
2
use crate :: ptr;
3
3
use crate :: sync:: atomic:: AtomicPtr ;
4
4
use crate :: sync:: atomic:: Ordering :: Relaxed ;
5
- use crate :: sys:: sync:: { Mutex , mutex } ;
5
+ use crate :: sys:: sync:: { Mutex , OnceBox } ;
6
6
#[ cfg( not( target_os = "nto" ) ) ]
7
7
use crate :: sys:: time:: TIMESPEC_MAX ;
8
8
#[ cfg( target_os = "nto" ) ]
9
9
use crate :: sys:: time:: TIMESPEC_MAX_CAPPED ;
10
- use crate :: sys_common:: lazy_box:: { LazyBox , LazyInit } ;
11
10
use crate :: time:: Duration ;
12
11
13
12
struct AllocatedCondvar ( UnsafeCell < libc:: pthread_cond_t > ) ;
14
13
15
14
pub struct Condvar {
16
- inner : LazyBox < AllocatedCondvar > ,
15
+ inner : OnceBox < AllocatedCondvar > ,
17
16
mutex : AtomicPtr < libc:: pthread_mutex_t > ,
18
17
}
19
18
20
- #[ inline]
21
- fn raw ( c : & Condvar ) -> * mut libc:: pthread_cond_t {
22
- c. inner . 0 . get ( )
23
- }
24
-
25
19
unsafe impl Send for AllocatedCondvar { }
26
20
unsafe impl Sync for AllocatedCondvar { }
27
21
28
- impl LazyInit for AllocatedCondvar {
29
- fn init ( ) -> Box < Self > {
22
+ impl AllocatedCondvar {
23
+ fn new ( ) -> Box < Self > {
30
24
let condvar = Box :: new ( AllocatedCondvar ( UnsafeCell :: new ( libc:: PTHREAD_COND_INITIALIZER ) ) ) ;
31
25
32
26
cfg_if:: cfg_if! {
@@ -37,7 +31,7 @@ impl LazyInit for AllocatedCondvar {
37
31
target_vendor = "apple" ,
38
32
) ) ] {
39
33
// `pthread_condattr_setclock` is unfortunately not supported on these platforms.
40
- } else if #[ cfg( any( target_os = "espidf" , target_os = "horizon" ) ) ] {
34
+ } else if #[ cfg( any( target_os = "espidf" , target_os = "horizon" , target_os = "teeos" ) ) ] {
41
35
// NOTE: ESP-IDF's PTHREAD_COND_INITIALIZER support is not released yet
42
36
// So on that platform, init() should always be called
43
37
// Moreover, that platform does not have pthread_condattr_setclock support,
@@ -82,7 +76,11 @@ impl Drop for AllocatedCondvar {
82
76
83
77
impl Condvar {
84
78
pub const fn new ( ) -> Condvar {
85
- Condvar { inner : LazyBox :: new ( ) , mutex : AtomicPtr :: new ( ptr:: null_mut ( ) ) }
79
+ Condvar { inner : OnceBox :: new ( ) , mutex : AtomicPtr :: new ( ptr:: null_mut ( ) ) }
80
+ }
81
+
82
+ fn get ( & self ) -> * mut libc:: pthread_cond_t {
83
+ self . inner . get_or_init ( AllocatedCondvar :: new) . 0 . get ( )
86
84
}
87
85
88
86
#[ inline]
@@ -98,21 +96,21 @@ impl Condvar {
98
96
99
97
#[ inline]
100
98
pub fn notify_one ( & self ) {
101
- let r = unsafe { libc:: pthread_cond_signal ( raw ( self ) ) } ;
99
+ let r = unsafe { libc:: pthread_cond_signal ( self . get ( ) ) } ;
102
100
debug_assert_eq ! ( r, 0 ) ;
103
101
}
104
102
105
103
#[ inline]
106
104
pub fn notify_all ( & self ) {
107
- let r = unsafe { libc:: pthread_cond_broadcast ( raw ( self ) ) } ;
105
+ let r = unsafe { libc:: pthread_cond_broadcast ( self . get ( ) ) } ;
108
106
debug_assert_eq ! ( r, 0 ) ;
109
107
}
110
108
111
109
#[ inline]
112
110
pub unsafe fn wait ( & self , mutex : & Mutex ) {
113
- let mutex = mutex:: raw ( mutex ) ;
111
+ let mutex = mutex. get_assert_locked ( ) ;
114
112
self . verify ( mutex) ;
115
- let r = libc:: pthread_cond_wait ( raw ( self ) , mutex) ;
113
+ let r = libc:: pthread_cond_wait ( self . get ( ) , mutex) ;
116
114
debug_assert_eq ! ( r, 0 ) ;
117
115
}
118
116
@@ -129,7 +127,7 @@ impl Condvar {
129
127
pub unsafe fn wait_timeout ( & self , mutex : & Mutex , dur : Duration ) -> bool {
130
128
use crate :: sys:: time:: Timespec ;
131
129
132
- let mutex = mutex:: raw ( mutex ) ;
130
+ let mutex = mutex. get_assert_locked ( ) ;
133
131
self . verify ( mutex) ;
134
132
135
133
#[ cfg( not( target_os = "nto" ) ) ]
@@ -144,7 +142,7 @@ impl Condvar {
144
142
. and_then ( |t| t. to_timespec_capped ( ) )
145
143
. unwrap_or ( TIMESPEC_MAX_CAPPED ) ;
146
144
147
- let r = libc:: pthread_cond_timedwait ( raw ( self ) , mutex, & timeout) ;
145
+ let r = libc:: pthread_cond_timedwait ( self . get ( ) , mutex, & timeout) ;
148
146
assert ! ( r == libc:: ETIMEDOUT || r == 0 ) ;
149
147
r == 0
150
148
}
@@ -162,7 +160,7 @@ impl Condvar {
162
160
use crate :: sys:: time:: SystemTime ;
163
161
use crate :: time:: Instant ;
164
162
165
- let mutex = mutex:: raw ( mutex ) ;
163
+ let mutex = mutex. get_assert_locked ( ) ;
166
164
self . verify ( mutex) ;
167
165
168
166
// OSX implementation of `pthread_cond_timedwait` is buggy
@@ -188,7 +186,7 @@ impl Condvar {
188
186
. and_then ( |t| t. to_timespec ( ) )
189
187
. unwrap_or ( TIMESPEC_MAX ) ;
190
188
191
- let r = libc:: pthread_cond_timedwait ( raw ( self ) , mutex, & timeout) ;
189
+ let r = libc:: pthread_cond_timedwait ( self . get ( ) , mutex, & timeout) ;
192
190
debug_assert ! ( r == libc:: ETIMEDOUT || r == 0 ) ;
193
191
194
192
// ETIMEDOUT is not a totally reliable method of determining timeout due
0 commit comments