Commit 0f0db6ab8e50
tarball1 file changed+16-6
@@ -1,5 +1,6 @@
1
-//! SIGINT and SIGTERM stop the event loop like `msg quit`, so the socket and2
-//! the X11 lock file are cleaned up when a session manager logs us out.1
+//! SIGINT, SIGTERM and SIGHUP stop the event loop like `msg quit`, so the2
+//! socket and the X11 lock file are cleaned up when a session manager logs us3
+//! out. A second one exits at once, for a shutdown that hangs.34
45
use crate::state::State;56
use smithay::reexports::calloop::generic::Generic;@@ -7,16 +8,25 @@ use smithay::reexports::calloop::{EventLoop, Interest, Mode, PostAction};
78
use std::io::{ErrorKind, Read};89
use std::os::fd::IntoRawFd;910
use std::os::unix::net::UnixStream;10
-use std::sync::atomic::{AtomicI32, Ordering};11
+use std::sync::atomic::{AtomicI32, AtomicU32, Ordering};1112
12
-const STOPPING: [libc::c_int; 2] = [libc::SIGINT, libc::SIGTERM];13
+const STOPPING: [libc::c_int; 3] = [libc::SIGINT, libc::SIGTERM, libc::SIGHUP];1314
1415
static WAKE: AtomicI32 = AtomicI32::new(-1);16
+static RECEIVED: AtomicU32 = AtomicU32::new(0);1517
1618
extern "C" fn on_signal(sig: libc::c_int) {1719
let byte = sig as u8;18
- // SAFETY: write is async-signal-safe and the buffer is a live local.19
- unsafe { libc::write(WAKE.load(Ordering::Relaxed), (&raw const byte).cast(), 1) };20
+ // SAFETY: _exit and write are async-signal-safe and the buffer is a live21
+ // local. The interrupted code may be reading errno, so it is put back.22
+ unsafe {23
+ if RECEIVED.fetch_add(1, Ordering::Relaxed) > 0 {24
+ libc::_exit(128 + sig);25
+ }26
+ let errno = *libc::__errno_location();27
+ libc::write(WAKE.load(Ordering::Relaxed), (&raw const byte).cast(), 1);28
+ *libc::__errno_location() = errno;29
+ }2030
}2131
2232
pub fn init(event_loop: &EventLoop<'static, State>) -> std::io::Result<()> {