Add names to threads and tasks for easier debugging of crashes
This commit is contained in:
parent
4061c059ac
commit
ec7f982bdf
4 changed files with 91 additions and 78 deletions
|
@ -144,7 +144,11 @@ fn main() {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn listen_for_daemon_response(mut recv: DaemonResponseReceiver) {
|
fn listen_for_daemon_response(mut recv: DaemonResponseReceiver) {
|
||||||
let rt = tokio::runtime::Builder::new_current_thread().enable_time().build().expect("Failed to initialize tokio runtime");
|
let rt = tokio::runtime::Builder::new_current_thread()
|
||||||
|
.thread_name("listen-for-daemon-response")
|
||||||
|
.enable_all()
|
||||||
|
.build()
|
||||||
|
.expect("Failed to initialize tokio runtime");
|
||||||
rt.block_on(async {
|
rt.block_on(async {
|
||||||
if let Ok(Some(response)) = tokio::time::timeout(Duration::from_millis(100), recv.recv()).await {
|
if let Ok(Some(response)) = tokio::time::timeout(Duration::from_millis(100), recv.recv()).await {
|
||||||
println!("{}", response);
|
println!("{}", response);
|
||||||
|
|
|
@ -24,32 +24,39 @@ use yuck::config::script_var_definition::{ListenScriptVar, PollScriptVar, Script
|
||||||
/// the script var execution.
|
/// the script var execution.
|
||||||
pub fn init(evt_send: UnboundedSender<DaemonCommand>) -> ScriptVarHandlerHandle {
|
pub fn init(evt_send: UnboundedSender<DaemonCommand>) -> ScriptVarHandlerHandle {
|
||||||
let (msg_send, mut msg_recv) = tokio::sync::mpsc::unbounded_channel();
|
let (msg_send, mut msg_recv) = tokio::sync::mpsc::unbounded_channel();
|
||||||
let thread_handle = std::thread::spawn(move || {
|
let thread_handle = std::thread::Builder::new()
|
||||||
let rt = tokio::runtime::Runtime::new().expect("Failed to initialize tokio runtime for script var handlers");
|
.name("outer-script-var-handler".to_string())
|
||||||
rt.block_on(async {
|
.spawn(move || {
|
||||||
let _: Result<_> = try {
|
let rt = tokio::runtime::Builder::new_multi_thread()
|
||||||
let mut handler = ScriptVarHandler {
|
.enable_all()
|
||||||
listen_handler: ListenVarHandler::new(evt_send.clone())?,
|
.thread_name("script-var-handler")
|
||||||
poll_handler: PollVarHandler::new(evt_send)?,
|
.build()
|
||||||
|
.expect("Failed to initialize tokio runtime for script var handlers");
|
||||||
|
rt.block_on(async {
|
||||||
|
let _: Result<_> = try {
|
||||||
|
let mut handler = ScriptVarHandler {
|
||||||
|
listen_handler: ListenVarHandler::new(evt_send.clone())?,
|
||||||
|
poll_handler: PollVarHandler::new(evt_send)?,
|
||||||
|
};
|
||||||
|
crate::loop_select_exiting! {
|
||||||
|
Some(msg) = msg_recv.recv() => match msg {
|
||||||
|
ScriptVarHandlerMsg::AddVar(var) => {
|
||||||
|
handler.add(var).await;
|
||||||
|
}
|
||||||
|
ScriptVarHandlerMsg::Stop(name) => {
|
||||||
|
handler.stop_for_variable(&name).await?;
|
||||||
|
}
|
||||||
|
ScriptVarHandlerMsg::StopAll => {
|
||||||
|
handler.stop_all().await;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
else => break,
|
||||||
|
};
|
||||||
};
|
};
|
||||||
crate::loop_select_exiting! {
|
})
|
||||||
Some(msg) = msg_recv.recv() => match msg {
|
|
||||||
ScriptVarHandlerMsg::AddVar(var) => {
|
|
||||||
handler.add(var).await;
|
|
||||||
}
|
|
||||||
ScriptVarHandlerMsg::Stop(name) => {
|
|
||||||
handler.stop_for_variable(&name).await?;
|
|
||||||
}
|
|
||||||
ScriptVarHandlerMsg::StopAll => {
|
|
||||||
handler.stop_all().await;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
else => break,
|
|
||||||
};
|
|
||||||
};
|
|
||||||
})
|
})
|
||||||
});
|
.expect("Failed to start script-var-handler thread");
|
||||||
let handle = ScriptVarHandlerHandle { msg_send, thread_handle };
|
let handle = ScriptVarHandlerHandle { msg_send, thread_handle };
|
||||||
handle
|
handle
|
||||||
}
|
}
|
||||||
|
@ -279,15 +286,6 @@ impl ListenVarHandler {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Drop for ListenVarHandler {
|
|
||||||
fn drop(&mut self) {
|
|
||||||
let rt = tokio::runtime::Runtime::new().expect("Failed to initialize tokio runtime for script var handlers");
|
|
||||||
rt.block_on(async {
|
|
||||||
self.stop_all().await;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn terminate_handle(mut child: tokio::process::Child) {
|
async fn terminate_handle(mut child: tokio::process::Child) {
|
||||||
if let Some(id) = child.id() {
|
if let Some(id) = child.id() {
|
||||||
log::debug!("Killing process with id {}", id);
|
log::debug!("Killing process with id {}", id);
|
||||||
|
|
|
@ -116,38 +116,46 @@ pub fn initialize_server(paths: EwwPaths, action: Option<DaemonCommand>, should_
|
||||||
}
|
}
|
||||||
|
|
||||||
fn init_async_part(paths: EwwPaths, ui_send: UnboundedSender<app::DaemonCommand>) {
|
fn init_async_part(paths: EwwPaths, ui_send: UnboundedSender<app::DaemonCommand>) {
|
||||||
std::thread::spawn(move || {
|
std::thread::Builder::new()
|
||||||
let rt = tokio::runtime::Builder::new_multi_thread().enable_all().build().expect("Failed to initialize tokio runtime");
|
.name("outer-main-async-runtime".to_string())
|
||||||
rt.block_on(async {
|
.spawn(move || {
|
||||||
let filewatch_join_handle = {
|
let rt = tokio::runtime::Builder::new_multi_thread()
|
||||||
let ui_send = ui_send.clone();
|
.thread_name("main-async-runtime")
|
||||||
let paths = paths.clone();
|
.enable_all()
|
||||||
tokio::spawn(async move { run_filewatch(paths.config_dir, ui_send).await })
|
.build()
|
||||||
};
|
.expect("Failed to initialize tokio runtime");
|
||||||
|
|
||||||
let ipc_server_join_handle = {
|
rt.block_on(async {
|
||||||
let ui_send = ui_send.clone();
|
let filewatch_join_handle = {
|
||||||
tokio::spawn(async move { ipc_server::run_server(ui_send, paths.get_ipc_socket_file()).await })
|
let ui_send = ui_send.clone();
|
||||||
};
|
let paths = paths.clone();
|
||||||
|
tokio::spawn(async move { run_filewatch(paths.config_dir, ui_send).await })
|
||||||
|
};
|
||||||
|
|
||||||
let forward_exit_to_app_handle = {
|
let ipc_server_join_handle = {
|
||||||
let ui_send = ui_send.clone();
|
let ui_send = ui_send.clone();
|
||||||
tokio::spawn(async move {
|
tokio::spawn(async move { ipc_server::run_server(ui_send, paths.get_ipc_socket_file()).await })
|
||||||
// Wait for application exit event
|
};
|
||||||
let _ = crate::application_lifecycle::recv_exit().await;
|
|
||||||
log::debug!("Forward task received exit event");
|
|
||||||
// Then forward that to the application
|
|
||||||
let _ = ui_send.send(app::DaemonCommand::KillServer);
|
|
||||||
})
|
|
||||||
};
|
|
||||||
|
|
||||||
let result = tokio::try_join!(filewatch_join_handle, ipc_server_join_handle, forward_exit_to_app_handle);
|
let forward_exit_to_app_handle = {
|
||||||
|
let ui_send = ui_send.clone();
|
||||||
|
tokio::spawn(async move {
|
||||||
|
// Wait for application exit event
|
||||||
|
let _ = crate::application_lifecycle::recv_exit().await;
|
||||||
|
log::debug!("Forward task received exit event");
|
||||||
|
// Then forward that to the application
|
||||||
|
let _ = ui_send.send(app::DaemonCommand::KillServer);
|
||||||
|
})
|
||||||
|
};
|
||||||
|
|
||||||
if let Err(e) = result {
|
let result = tokio::try_join!(filewatch_join_handle, ipc_server_join_handle, forward_exit_to_app_handle);
|
||||||
log::error!("Eww exiting with error: {:?}", e);
|
|
||||||
}
|
if let Err(e) = result {
|
||||||
|
log::error!("Eww exiting with error: {:?}", e);
|
||||||
|
}
|
||||||
|
})
|
||||||
})
|
})
|
||||||
});
|
.expect("Failed to start outer-main-async-runtime thread");
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Watch configuration files for changes, sending reload events to the eww app when the files change.
|
/// Watch configuration files for changes, sending reload events to the eww app when the files change.
|
||||||
|
|
|
@ -17,23 +17,26 @@ where
|
||||||
{
|
{
|
||||||
use wait_timeout::ChildExt;
|
use wait_timeout::ChildExt;
|
||||||
let cmd = replace_placeholders(cmd, args);
|
let cmd = replace_placeholders(cmd, args);
|
||||||
std::thread::spawn(move || {
|
std::thread::Builder::new()
|
||||||
log::debug!("Running command from widget: {}", cmd);
|
.name("command-execution-thread".to_string())
|
||||||
let child = Command::new("/bin/sh").arg("-c").arg(&cmd).spawn();
|
.spawn(move || {
|
||||||
match child {
|
log::debug!("Running command from widget: {}", cmd);
|
||||||
Ok(mut child) => match child.wait_timeout(timeout) {
|
let child = Command::new("/bin/sh").arg("-c").arg(&cmd).spawn();
|
||||||
// child timed out
|
match child {
|
||||||
Ok(None) => {
|
Ok(mut child) => match child.wait_timeout(timeout) {
|
||||||
log::error!("WARNING: command {} timed out", &cmd);
|
// child timed out
|
||||||
let _ = child.kill();
|
Ok(None) => {
|
||||||
let _ = child.wait();
|
log::error!("WARNING: command {} timed out", &cmd);
|
||||||
}
|
let _ = child.kill();
|
||||||
Err(err) => log::error!("Failed to execute command {}: {}", cmd, err),
|
let _ = child.wait();
|
||||||
Ok(Some(_)) => {}
|
}
|
||||||
},
|
Err(err) => log::error!("Failed to execute command {}: {}", cmd, err),
|
||||||
Err(err) => log::error!("Failed to launch child process: {}", err),
|
Ok(Some(_)) => {}
|
||||||
}
|
},
|
||||||
});
|
Err(err) => log::error!("Failed to launch child process: {}", err),
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.expect("Failed to start command-execution-thread");
|
||||||
}
|
}
|
||||||
|
|
||||||
fn replace_placeholders<T>(cmd: &str, args: &[T]) -> String
|
fn replace_placeholders<T>(cmd: &str, args: &[T]) -> String
|
||||||
|
|
Loading…
Add table
Reference in a new issue