9
9
10
10
use crate :: error:: Error as CtrlcError ;
11
11
12
- static mut SEMAPHORE : nix:: libc:: sem_t = unsafe { std:: mem:: zeroed ( ) } ;
13
- const SEM_THREAD_SHARED : nix:: libc:: c_int = 0 ;
12
+ #[ cfg( not( target_vendor = "apple" ) ) ]
13
+ #[ allow( static_mut_refs) ] // rust-version = "1.69.0"
14
+ mod implementation {
15
+ static mut SEMAPHORE : nix:: libc:: sem_t = unsafe { std:: mem:: zeroed ( ) } ;
16
+ const SEM_THREAD_SHARED : nix:: libc:: c_int = 0 ;
17
+
18
+ pub unsafe fn sem_init ( ) {
19
+ nix:: libc:: sem_init ( & mut SEMAPHORE as * mut _ , SEM_THREAD_SHARED , 0 ) ;
20
+ }
21
+
22
+ pub unsafe fn sem_post ( ) {
23
+ // No errors apply. EOVERFLOW is hypothetically possible but it's equivalent to a success for our oneshot use-casse.
24
+ let _ = nix:: libc:: sem_post ( & mut SEMAPHORE as * mut _ ) ;
25
+ }
26
+
27
+ pub unsafe fn sem_wait_forever ( ) {
28
+ // The only realistic error is EINTR, which is restartable.
29
+ while nix:: libc:: sem_wait ( & mut SEMAPHORE as * mut _ ) == -1 { }
30
+ }
31
+ }
32
+
33
+ #[ cfg( target_vendor = "apple" ) ]
34
+ mod implementation {
35
+ static mut SEMAPHORE : dispatch:: ffi:: dispatch_semaphore_t = std:: ptr:: null_mut ( ) ;
36
+
37
+ pub unsafe fn sem_init ( ) {
38
+ SEMAPHORE = dispatch:: ffi:: dispatch_semaphore_create ( 0 ) ;
39
+ }
40
+
41
+ pub unsafe fn sem_post ( ) {
42
+ dispatch:: ffi:: dispatch_semaphore_signal ( SEMAPHORE ) ;
43
+ }
44
+
45
+ pub unsafe fn sem_wait_forever ( ) {
46
+ dispatch:: ffi:: dispatch_semaphore_wait ( SEMAPHORE , dispatch:: ffi:: DISPATCH_TIME_FOREVER ) ;
47
+ }
48
+ }
14
49
15
50
/// Platform specific error type
16
51
pub type Error = nix:: Error ;
@@ -20,8 +55,7 @@ pub type Signal = nix::sys::signal::Signal;
20
55
21
56
extern "C" fn os_handler ( _: nix:: libc:: c_int ) {
22
57
unsafe {
23
- // No errors apply. EOVERFLOW is hypothetically possible but it's equivalent to a success for our oneshot use-casse.
24
- let _ = nix:: libc:: sem_post ( & raw mut SEMAPHORE ) ;
58
+ implementation:: sem_post ( ) ;
25
59
}
26
60
}
27
61
@@ -37,7 +71,7 @@ extern "C" fn os_handler(_: nix::libc::c_int) {
37
71
pub unsafe fn init_os_handler ( overwrite : bool ) -> Result < ( ) , Error > {
38
72
use nix:: sys:: signal;
39
73
40
- nix :: libc :: sem_init ( & raw mut SEMAPHORE , SEM_THREAD_SHARED , 0 ) ;
74
+ implementation :: sem_init ( ) ;
41
75
42
76
let handler = signal:: SigHandler :: Handler ( os_handler) ;
43
77
#[ cfg( not( target_os = "nto" ) ) ]
@@ -99,7 +133,6 @@ pub unsafe fn init_os_handler(overwrite: bool) -> Result<(), Error> {
99
133
///
100
134
#[ inline]
101
135
pub unsafe fn block_ctrl_c ( ) -> Result < ( ) , CtrlcError > {
102
- // The only realistic error is EINTR, which is restartable.
103
- while nix:: libc:: sem_wait ( & raw mut SEMAPHORE ) == -1 { }
136
+ implementation:: sem_wait_forever ( ) ;
104
137
Ok ( ( ) )
105
138
}
0 commit comments