99
1010use crate :: error:: Error as CtrlcError ;
1111
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-case.
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+ }
1449
1550/// Platform specific error type
1651pub type Error = nix:: Error ;
@@ -20,8 +55,7 @@ pub type Signal = nix::sys::signal::Signal;
2055
2156extern "C" fn os_handler ( _: nix:: libc:: c_int ) {
2257 unsafe {
23- // No errors apply. EOVERFLOW is hypothetically possible but it's equivalent to a success for our oneshot use-case.
24- let _ = nix:: libc:: sem_post ( & raw mut SEMAPHORE ) ;
58+ implementation:: sem_post ( ) ;
2559 }
2660}
2761
@@ -37,7 +71,7 @@ extern "C" fn os_handler(_: nix::libc::c_int) {
3771pub unsafe fn init_os_handler ( overwrite : bool ) -> Result < ( ) , Error > {
3872 use nix:: sys:: signal;
3973
40- nix :: libc :: sem_init ( & raw mut SEMAPHORE , SEM_THREAD_SHARED , 0 ) ;
74+ implementation :: sem_init ( ) ;
4175
4276 let handler = signal:: SigHandler :: Handler ( os_handler) ;
4377 #[ cfg( not( target_os = "nto" ) ) ]
@@ -99,7 +133,6 @@ pub unsafe fn init_os_handler(overwrite: bool) -> Result<(), Error> {
99133///
100134#[ inline]
101135pub 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 ( ) ;
104137 Ok ( ( ) )
105138}
0 commit comments