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]
#[cfg(unix)]
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
#[inline]
#[cfg(not(unix))]
fn is_shutting_down(&self) -> bool {
true
false
}
/// Loops infinitely, forwarding and handling all incoming messages from clients.

View File

@ -4,6 +4,8 @@ use core::{
convert::TryFrom,
fmt::{self, Display, Formatter},
mem, ptr,
ptr::write_volatile,
sync::atomic::{compiler_fence, Ordering},
};
#[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;
let signals = handler.signals();
for sig in signals {
SIGNAL_HANDLERS[sig as usize] = Some(HandlerHolder {
write_volatile(
&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 {
#[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)));
}
}
compiler_fence(Ordering::SeqCst);
Ok(())
}

View File

@ -3,7 +3,10 @@
use core::marker::PhantomData;
#[cfg(unix)]
use core::ptr;
use core::{
ptr::{self, write_volatile},
sync::atomic::{compiler_fence, Ordering},
};
#[cfg(unix)]
use crate::bolts::os::unix_signals::{c_void, setup_signal_handler};
@ -52,11 +55,15 @@ where
#[cfg(unix)]
unsafe {
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.
// 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;
data.event_mgr_ptr = _event_mgr as *mut _ as *mut c_void;
write_volatile(&mut data.state_ptr, _state 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(())
}
@ -67,7 +74,11 @@ where
let ret = (self.harness_fn)(self, bytes.as_slice());
#[cfg(unix)]
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)
}
@ -126,13 +137,22 @@ where
{
#[cfg(unix)]
unsafe {
let mut data = &mut unix_signal_handler::GLOBAL_STATE;
data.observers_ptr = &observers as *const _ as *const c_void;
data.crash_handler = unix_signal_handler::inproc_crash_handler::<EM, I, OC, OFT, OT, S>;
data.timeout_handler =
unix_signal_handler::inproc_timeout_handler::<EM, I, OC, OFT, OT, S>;
let data = &mut unix_signal_handler::GLOBAL_STATE;
write_volatile(
&mut data.observers_ptr,
&observers as *const _ as *const c_void,
);
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)?;
compiler_fence(Ordering::SeqCst);
}
Ok(Self {