mirror of
https://github.com/tinyhumansai/openhuman.git
synced 2026-07-27 21:08:00 +00:00
refactor: improve macOS event handling and TDLib shutdown process
- Updated the event handling in the Tauri application to use a match statement for better clarity and maintainability. - Added graceful shutdown logic for TDLib during application exit to prevent crashes related to C++ destructors. - Enhanced the TDLib manager to signal shutdown and exit the receive loop cleanly, improving application stability.
This commit is contained in:
+26
-8
@@ -574,14 +574,32 @@ pub fn run() {
|
||||
.build(tauri::generate_context!())
|
||||
.expect("error while building tauri application")
|
||||
.run(|app_handle, event| {
|
||||
// Handle macOS Dock icon click (reopen event)
|
||||
#[cfg(target_os = "macos")]
|
||||
if let RunEvent::Reopen { .. } = event {
|
||||
show_main_window(app_handle);
|
||||
}
|
||||
match event {
|
||||
// Handle macOS Dock icon click (reopen event)
|
||||
#[cfg(target_os = "macos")]
|
||||
RunEvent::Reopen { .. } => {
|
||||
show_main_window(app_handle);
|
||||
}
|
||||
|
||||
// Suppress unused variable warnings on other platforms
|
||||
#[cfg(not(target_os = "macos"))]
|
||||
let _ = (app_handle, event);
|
||||
// Gracefully shut down TDLib before process exit to prevent
|
||||
// use-after-free crash in the blocking receive loop.
|
||||
#[cfg(not(any(target_os = "android", target_os = "ios")))]
|
||||
RunEvent::Exit => {
|
||||
log::info!("[app] Exit event received, shutting down TDLib");
|
||||
use crate::services::tdlib::TDLIB_MANAGER;
|
||||
// Signal the TDLib worker to stop. The blocking receive() call
|
||||
// has a 2-second internal timeout, so we must wait long enough
|
||||
// for any in-flight call to finish before process teardown runs
|
||||
// C++ destructors on TDLib's internal state.
|
||||
TDLIB_MANAGER.signal_shutdown();
|
||||
std::thread::sleep(std::time::Duration::from_millis(2500));
|
||||
log::info!("[app] TDLib shutdown wait complete");
|
||||
let _ = app_handle;
|
||||
}
|
||||
|
||||
_ => {
|
||||
let _ = app_handle;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -179,14 +179,20 @@ impl TdLibManager {
|
||||
let poll_handle = tokio::spawn(async move {
|
||||
loop {
|
||||
if !state_clone.is_active.load(Ordering::SeqCst) {
|
||||
log::info!("[tdlib] Receive loop exiting (shutdown signalled)");
|
||||
break;
|
||||
}
|
||||
|
||||
// Use spawn_blocking for the blocking TDLib receive call
|
||||
let receive_result = tokio::task::spawn_blocking(|| {
|
||||
// Use a short timeout to be more responsive
|
||||
// Note: tdlib_rs::receive() uses 2.0s internally, but that's OK
|
||||
// because we're in spawn_blocking and won't block the async runtime
|
||||
// Clone the Arc so we can check is_active inside
|
||||
// spawn_blocking *before* entering the 2-second blocking
|
||||
// td_receive() FFI call. This minimises the window where
|
||||
// a process-exit could tear down TDLib state while we're
|
||||
// inside the C++ code.
|
||||
let state_for_recv = state_clone.clone();
|
||||
let receive_result = tokio::task::spawn_blocking(move || {
|
||||
if !state_for_recv.is_active.load(Ordering::SeqCst) {
|
||||
return None;
|
||||
}
|
||||
tdlib_rs::receive()
|
||||
})
|
||||
.await;
|
||||
@@ -504,6 +510,13 @@ impl TdLibManager {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Signal the TDLib worker to stop (non-async, safe to call from any context).
|
||||
/// This is used during app exit to prevent the receive loop from crashing
|
||||
/// when TDLib's C++ static destructors run during process shutdown.
|
||||
pub fn signal_shutdown(&self) {
|
||||
self.state.is_active.store(false, Ordering::SeqCst);
|
||||
}
|
||||
|
||||
/// Check if the client is active.
|
||||
pub fn is_active(&self) -> bool {
|
||||
self.state.is_active.load(Ordering::SeqCst) && self.client_id.read().is_some()
|
||||
|
||||
@@ -41,7 +41,7 @@
|
||||
"macOS": {
|
||||
"minimumSystemVersion": "10.15",
|
||||
"dmg": {
|
||||
"background": "./images/background-dmg.svg"
|
||||
"background": "./images/background-dmg.png"
|
||||
},
|
||||
"frameworks": [
|
||||
"./libraries/libtdjson.1.8.29.dylib",
|
||||
|
||||
Reference in New Issue
Block a user