fn event_requires_infinite_sleep_in_handler(signum: u32) -> bool { // Returning from the handler function of those events immediately terminates the process. // So for async systems, the easiest solution is to simply never return from // the handler function. // // For more information, see: // https://learn.microsoft.com/en-us/windows/console/handlerroutine#remarks
matches!(
signum,
console::CTRL_CLOSE_EVENT | console::CTRL_LOGOFF_EVENT | console::CTRL_SHUTDOWN_EVENT
)
}
unsafeextern"system"fn handler(ty: u32) -> BOOL { // Ignore unknown control signal types. let Some(event_info) = registry().event_info(ty) else { return0;
};
// According to https://learn.microsoft.com/en-us/windows/console/handlerroutine // the handler routine is always invoked in a new thread, thus we don't // have the same restrictions as in Unix signal handlers, meaning we can // go ahead and perform the broadcast here. match event_info.send(()) {
Ok(_) if event_requires_infinite_sleep_in_handler(ty) => loop {
std::thread::park();
},
Ok(_) => 1, // No one is listening for this notification any more // let the OS fire the next (possibly the default) handler.
Err(_) => 0,
}
}
#[cfg(all(test, not(loom)))] mod tests { usesuper::*; usecrate::runtime::Runtime;
use tokio_test::{assert_ok, assert_pending, assert_ready_ok, task};
unsafefn raise_event(signum: u32) { if event_requires_infinite_sleep_in_handler(signum) { // Those events will enter an infinite loop in `handler`, so // we need to run them on a separate thread
std::thread::spawn(move || unsafe { super::handler(signum) });
} else { unsafe { super::handler(signum) };
}
}
#[test] fn ctrl_c() { let rt = rt(); let _enter = rt.enter();
// Windows doesn't have a good programmatic way of sending events // like sending signals on Unix, so we'll stub out the actual OS // integration and test that our handling works. unsafe {
raise_event(console::CTRL_C_EVENT);
}
// Windows doesn't have a good programmatic way of sending events // like sending signals on Unix, so we'll stub out the actual OS // integration and test that our handling works. unsafe {
raise_event(console::CTRL_BREAK_EVENT);
}
// Windows doesn't have a good programmatic way of sending events // like sending signals on Unix, so we'll stub out the actual OS // integration and test that our handling works. unsafe {
raise_event(console::CTRL_CLOSE_EVENT);
}
// Windows doesn't have a good programmatic way of sending events // like sending signals on Unix, so we'll stub out the actual OS // integration and test that our handling works. unsafe {
raise_event(console::CTRL_SHUTDOWN_EVENT);
}
// Windows doesn't have a good programmatic way of sending events // like sending signals on Unix, so we'll stub out the actual OS // integration and test that our handling works. unsafe {
raise_event(console::CTRL_LOGOFF_EVENT);
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.