Fix shutdown deadlock
Calling ::std::process::exit() from the SIGCHLD handler would sometimes deadlock some OpenGL internal shutdown procedure. To resolve this, a flag was added that can be checked with `process_should_exit`.
This commit is contained in:
parent
8126841ed3
commit
8b1e82f31a
10
src/main.rs
10
src/main.rs
|
@ -44,6 +44,7 @@ use grid::Grid;
|
|||
use term::Term;
|
||||
use meter::Meter;
|
||||
use util::thread;
|
||||
use tty::process_should_exit;
|
||||
|
||||
#[derive(Debug, Eq, PartialEq, Copy, Clone, Default)]
|
||||
pub struct Rgb {
|
||||
|
@ -130,7 +131,7 @@ fn main() {
|
|||
}
|
||||
|
||||
let (chars_tx, chars_rx) = ::std::sync::mpsc::channel();
|
||||
thread::spawn_named("TTY Reader", move || {
|
||||
let reader_thread = thread::spawn_named("TTY Reader", move || {
|
||||
for c in reader.chars() {
|
||||
let c = c.unwrap();
|
||||
chars_tx.send(c).unwrap();
|
||||
|
@ -219,8 +220,13 @@ fn main() {
|
|||
|
||||
window.swap_buffers().unwrap();
|
||||
}
|
||||
|
||||
if process_should_exit() {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO handle child cleanup
|
||||
reader_thread.join();
|
||||
println!("Goodbye");
|
||||
}
|
||||
|
||||
|
|
13
src/tty.rs
13
src/tty.rs
|
@ -14,6 +14,13 @@ use libc::{self, winsize, c_int, c_char, pid_t, WNOHANG, WIFEXITED, WEXITSTATUS,
|
|||
/// Necessary to put this in static storage for `sigchld` to have access
|
||||
static mut PID: pid_t = 0;
|
||||
|
||||
/// Exit flag
|
||||
///
|
||||
/// Calling exit() in the SIGCHLD handler sometimes causes opengl to deadlock,
|
||||
/// and the process hangs. Instead, this flag is set, and its status can be
|
||||
/// cheked via `process_should_exit`.
|
||||
static mut SHOULD_EXIT: bool = false;
|
||||
|
||||
extern "C" fn sigchld(a: c_int) {
|
||||
let mut status: c_int = 0;
|
||||
unsafe {
|
||||
|
@ -29,9 +36,13 @@ extern "C" fn sigchld(a: c_int) {
|
|||
if !WIFEXITED(status) || WEXITSTATUS(status) != 0 {
|
||||
die!("child finished with error '{}'\n", status);
|
||||
}
|
||||
|
||||
SHOULD_EXIT = true;
|
||||
}
|
||||
}
|
||||
|
||||
::std::process::exit(0);
|
||||
pub fn process_should_exit() -> bool {
|
||||
unsafe { SHOULD_EXIT }
|
||||
}
|
||||
|
||||
pub enum Error {
|
||||
|
|
Loading…
Reference in New Issue