volatile for signal handlers

This commit is contained in:
Dominik Maier 2021-03-06 16:32:42 +01:00
parent edd239ce95
commit 8459997d9f
3 changed files with 41 additions and 15 deletions

View File

@ -1347,14 +1347,14 @@ where
#[inline] #[inline]
#[cfg(unix)] #[cfg(unix)]
fn is_shutting_down(&self) -> bool { fn is_shutting_down(&self) -> bool {
unsafe { !ptr::read_volatile(&GLOBAL_SIGHANDLER_STATE.shutting_down) } unsafe { ptr::read_volatile(&GLOBAL_SIGHANDLER_STATE.shutting_down) }
} }
/// Always returns true on platforms, where no shutdown signal handlers are supported /// Always returns true on platforms, where no shutdown signal handlers are supported
#[inline] #[inline]
#[cfg(not(unix))] #[cfg(not(unix))]
fn is_shutting_down(&self) -> bool { fn is_shutting_down(&self) -> bool {
true false
} }
/// Loops infinitely, forwarding and handling all incoming messages from clients. /// Loops infinitely, forwarding and handling all incoming messages from clients.

View File

@ -4,6 +4,8 @@ use core::{
convert::TryFrom, convert::TryFrom,
fmt::{self, Display, Formatter}, fmt::{self, Display, Formatter},
mem, ptr, mem, ptr,
ptr::write_volatile,
sync::atomic::{compiler_fence, Ordering},
}; };
#[cfg(feature = "std")] #[cfg(feature = "std")]
@ -151,9 +153,12 @@ pub unsafe fn setup_signal_handler<T: 'static + Handler>(handler: &mut T) -> Res
sa.sa_sigaction = handle_signal as usize; sa.sa_sigaction = handle_signal as usize;
let signals = handler.signals(); let signals = handler.signals();
for sig in signals { for sig in signals {
SIGNAL_HANDLERS[sig as usize] = Some(HandlerHolder { write_volatile(
handler: UnsafeCell::new(handler as *mut dyn Handler), &mut SIGNAL_HANDLERS[sig as usize],
}); Some(HandlerHolder {
handler: UnsafeCell::new(handler as *mut dyn Handler),
}),
);
if sigaction(sig as i32, &mut sa as *mut sigaction, ptr::null_mut()) < 0 { if sigaction(sig as i32, &mut sa as *mut sigaction, ptr::null_mut()) < 0 {
#[cfg(feature = "std")] #[cfg(feature = "std")]
@ -164,6 +169,7 @@ pub unsafe fn setup_signal_handler<T: 'static + Handler>(handler: &mut T) -> Res
return Err(Error::Unknown(format!("Could not set up {} handler", sig))); return Err(Error::Unknown(format!("Could not set up {} handler", sig)));
} }
} }
compiler_fence(Ordering::SeqCst);
Ok(()) Ok(())
} }

View File

@ -3,7 +3,10 @@
use core::marker::PhantomData; use core::marker::PhantomData;
#[cfg(unix)] #[cfg(unix)]
use core::ptr; use core::{
ptr::{self, write_volatile},
sync::atomic::{compiler_fence, Ordering},
};
#[cfg(unix)] #[cfg(unix)]
use crate::bolts::os::unix_signals::{c_void, setup_signal_handler}; use crate::bolts::os::unix_signals::{c_void, setup_signal_handler};
@ -52,11 +55,15 @@ where
#[cfg(unix)] #[cfg(unix)]
unsafe { unsafe {
let data = &mut unix_signal_handler::GLOBAL_STATE; let data = &mut unix_signal_handler::GLOBAL_STATE;
data.current_input_ptr = _input as *const _ as *const c_void; write_volatile(
&mut data.current_input_ptr,
_input as *const _ as *const c_void,
);
// Direct raw pointers access /aliasing is pretty undefined behavior. // Direct raw pointers access /aliasing is pretty undefined behavior.
// Since the state and event may have moved in memory, refresh them right before the signal may happen // Since the state and event may have moved in memory, refresh them right before the signal may happen
data.state_ptr = _state as *mut _ as *mut c_void; write_volatile(&mut data.state_ptr, _state as *mut _ as *mut c_void);
data.event_mgr_ptr = _event_mgr as *mut _ as *mut c_void; write_volatile(&mut data.event_mgr_ptr, _event_mgr as *mut _ as *mut c_void);
compiler_fence(Ordering::SeqCst);
} }
Ok(()) Ok(())
} }
@ -67,7 +74,11 @@ where
let ret = (self.harness_fn)(self, bytes.as_slice()); let ret = (self.harness_fn)(self, bytes.as_slice());
#[cfg(unix)] #[cfg(unix)]
unsafe { unsafe {
unix_signal_handler::GLOBAL_STATE.current_input_ptr = ptr::null(); write_volatile(
&mut unix_signal_handler::GLOBAL_STATE.current_input_ptr,
ptr::null(),
);
compiler_fence(Ordering::SeqCst);
} }
Ok(ret) Ok(ret)
} }
@ -126,13 +137,22 @@ where
{ {
#[cfg(unix)] #[cfg(unix)]
unsafe { unsafe {
let mut data = &mut unix_signal_handler::GLOBAL_STATE; let data = &mut unix_signal_handler::GLOBAL_STATE;
data.observers_ptr = &observers as *const _ as *const c_void; write_volatile(
data.crash_handler = unix_signal_handler::inproc_crash_handler::<EM, I, OC, OFT, OT, S>; &mut data.observers_ptr,
data.timeout_handler = &observers as *const _ as *const c_void,
unix_signal_handler::inproc_timeout_handler::<EM, I, OC, OFT, OT, S>; );
write_volatile(
&mut data.crash_handler,
unix_signal_handler::inproc_crash_handler::<EM, I, OC, OFT, OT, S>,
);
write_volatile(
&mut data.timeout_handler,
unix_signal_handler::inproc_timeout_handler::<EM, I, OC, OFT, OT, S>,
);
setup_signal_handler(data)?; setup_signal_handler(data)?;
compiler_fence(Ordering::SeqCst);
} }
Ok(Self { Ok(Self {