summaryrefslogtreecommitdiffstats
path: root/src/state.rs
diff options
context:
space:
mode:
authorManos Pitsidianakis <el13635@mail.ntua.gr>2020-07-21 19:22:56 +0300
committerManos Pitsidianakis <el13635@mail.ntua.gr>2020-07-23 13:23:23 +0300
commit44ffbe54e238f2d69609f902a7554c72b74a955d (patch)
tree6a3405e9c39a233b39c07bf20d47a6c056255ae2 /src/state.rs
parent0882dbbad025f9f4f072f8a30564f417b37aa935 (diff)
input_thread: add atomic refcount to check if thread is dead
Diffstat (limited to 'src/state.rs')
-rw-r--r--src/state.rs39
1 files changed, 31 insertions, 8 deletions
diff --git a/src/state.rs b/src/state.rs
index 2c8a4a9e..91f3c389 100644
--- a/src/state.rs
+++ b/src/state.rs
@@ -51,16 +51,22 @@ struct InputHandler {
pipe: (RawFd, RawFd),
rx: Receiver<InputCommand>,
tx: Sender<InputCommand>,
+ state_tx: Sender<ThreadEvent>,
+ control: std::sync::Weak<()>,
}
impl InputHandler {
- fn restore(&self, tx: Sender<ThreadEvent>) {
+ fn restore(&mut self) {
+ let working = Arc::new(());
+ let control = Arc::downgrade(&working);
+
/* Clear channel without blocking. switch_to_main_screen() issues a kill when
* returning from a fork and there's no input thread, so the newly created thread will
* receive it and die. */
//let _ = self.rx.try_iter().count();
let rx = self.rx.clone();
let pipe = self.pipe.0;
+ let tx = self.state_tx.clone();
thread::Builder::new()
.name("input-thread".to_string())
.spawn(move || {
@@ -70,15 +76,27 @@ impl InputHandler {
},
&rx,
pipe,
+ working,
)
})
.unwrap();
+ self.control = control;
}
fn kill(&self) {
let _ = nix::unistd::write(self.pipe.1, &[1]);
self.tx.send(InputCommand::Kill).unwrap();
}
+
+ fn check(&mut self) {
+ match self.control.upgrade() {
+ Some(_) => {}
+ None => {
+ debug!("restarting input_thread");
+ self.restore();
+ }
+ }
+ }
}
/// A context container for loaded settings, accounts, UI changes, etc.
@@ -95,7 +113,7 @@ pub struct Context {
pub replies: VecDeque<UIEvent>,
sender: Sender<ThreadEvent>,
receiver: Receiver<ThreadEvent>,
- input: InputHandler,
+ input_thread: InputHandler,
work_controller: WorkController,
job_executor: Arc<JobExecutor>,
pub children: Vec<std::process::Child>,
@@ -110,11 +128,11 @@ impl Context {
}
pub fn input_kill(&self) {
- self.input.kill();
+ self.input_thread.kill();
}
- pub fn restore_input(&self) {
- self.input.restore(self.sender.clone());
+ pub fn restore_input(&mut self) {
+ self.input_thread.restore();
}
pub fn is_online(&mut self, account_pos: usize) -> Result<()> {
@@ -299,6 +317,8 @@ impl State {
timer.thread().unpark();
+ let working = Arc::new(());
+ let control = Arc::downgrade(&working);
let mut s = State {
cols,
rows,
@@ -334,13 +354,15 @@ impl State {
children: vec![],
plugin_manager,
- sender,
- receiver,
- input: InputHandler {
+ input_thread: InputHandler {
pipe: input_thread_pipe,
rx: input_thread.1,
tx: input_thread.0,
+ control,
+ state_tx: sender.clone(),
},
+ sender,
+ receiver,
},
};
s.draw_rate_limit
@@ -1128,5 +1150,6 @@ impl State {
if ctr != self.context.accounts.len() {
self.timer.thread().unpark();
}
+ self.context.input_thread.check();
}
}