safe exit

This commit is contained in:
rustdesk 2021-08-09 04:21:42 +08:00
parent 8affa24400
commit bb25964307
5 changed files with 82 additions and 35 deletions

19
Cargo.lock generated
View File

@ -915,6 +915,19 @@ dependencies = [
"termcolor", "termcolor",
] ]
[[package]]
name = "env_logger"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b2cf0344971ee6c64c31be0d530793fba457d322dfec2810c453d0ef228f9c3"
dependencies = [
"atty",
"humantime",
"log",
"regex",
"termcolor",
]
[[package]] [[package]]
name = "err-derive" name = "err-derive"
version = "0.2.4" version = "0.2.4"
@ -978,9 +991,9 @@ dependencies = [
[[package]] [[package]]
name = "flexi_logger" name = "flexi_logger"
version = "0.16.3" version = "0.17.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "291b6ce7b3ed2dda82efa6aee4c6bdb55fd11bc88b06c55b01851e94b96e5322" checksum = "33ab94b6ac8eb69f1496a6993f26f785b5fd6d99b7416023eb2a6175c0b242b1"
dependencies = [ dependencies = [
"atty", "atty",
"chrono", "chrono",
@ -1377,7 +1390,7 @@ dependencies = [
"confy", "confy",
"directories-next", "directories-next",
"dirs-next", "dirs-next",
"env_logger 0.8.4", "env_logger 0.9.0",
"filetime", "filetime",
"futures", "futures",
"futures-util", "futures-util",

View File

@ -30,7 +30,7 @@ sha2 = "0.9"
repng = "0.2" repng = "0.2"
libc = "0.2" libc = "0.2"
parity-tokio-ipc = { git = "https://github.com/open-trade/parity-tokio-ipc" } parity-tokio-ipc = { git = "https://github.com/open-trade/parity-tokio-ipc" }
flexi_logger = "0.16" flexi_logger = "0.17"
runas = "0.2" runas = "0.2"
magnum-opus = { git = "https://github.com/open-trade/magnum-opus" } magnum-opus = { git = "https://github.com/open-trade/magnum-opus" }
dasp = { version = "0.11", features = ["signal", "interpolate-linear", "interpolate"], optional = true } dasp = { version = "0.11", features = ["signal", "interpolate-linear", "interpolate"], optional = true }

View File

@ -171,6 +171,7 @@ async fn handle(data: Data, stream: &mut Connection) {
} }
Data::Close => { Data::Close => {
log::info!("Receive close message"); log::info!("Receive close message");
crate::server::input_service::fix_key_down_timeout_at_exit();
std::process::exit(0); std::process::exit(0);
} }
Data::OnlineStatus(_) => { Data::OnlineStatus(_) => {

View File

@ -272,7 +272,7 @@ pub async fn start_server(is_server: bool, _tray: bool) {
std::process::exit(-1); std::process::exit(-1);
} }
}); });
input_service::fix_key_down_timeout(); input_service::fix_key_down_timeout_loop();
crate::RendezvousMediator::start_all().await; crate::RendezvousMediator::start_all().await;
} else { } else {
match crate::ipc::connect(1000, "").await { match crate::ipc::connect(1000, "").await {

View File

@ -159,6 +159,7 @@ fn run_cursor(sp: MouseCursorService, state: &mut StateCursor) -> ResultType<()>
lazy_static::lazy_static! { lazy_static::lazy_static! {
static ref ENIGO: Arc<Mutex<Enigo>> = Arc::new(Mutex::new(Enigo::new())); static ref ENIGO: Arc<Mutex<Enigo>> = Arc::new(Mutex::new(Enigo::new()));
static ref KEYS_DOWN: Arc<Mutex<HashMap<i32, Instant>>> = Default::default(); static ref KEYS_DOWN: Arc<Mutex<HashMap<i32, Instant>>> = Default::default();
static ref EXITING: Arc<Mutex<bool>> = Default::default();
} }
// mac key input must be run in main thread, otherwise crash on >= osx 10.15 // mac key input must be run in main thread, otherwise crash on >= osx 10.15
@ -212,42 +213,66 @@ pub fn handle_mouse(evt: &MouseEvent, conn: i32) {
handle_mouse_(evt, conn); handle_mouse_(evt, conn);
} }
pub fn fix_key_down_timeout() { pub fn fix_key_down_timeout_loop() {
std::thread::spawn(move || loop { std::thread::spawn(move || loop {
std::thread::sleep(std::time::Duration::from_millis(300)); std::thread::sleep(std::time::Duration::from_millis(300));
if KEYS_DOWN.lock().unwrap().is_empty() { fix_key_down_timeout(false);
continue; });
} // atexit is called before exit
let cloned = (*KEYS_DOWN.lock().unwrap()).clone(); unsafe { libc::atexit(fix_key_down_timeout_at_exit) };
log::debug!("{} keys in key down timeout map", cloned.len()); unsafe {
for (key, value) in cloned.into_iter() { libc::signal(libc::SIGINT, fix_key_down_timeout_at_signal as _);
if value.elapsed().as_millis() >= 3_000 { }
KEYS_DOWN.lock().unwrap().remove(&key); }
let key = if key < KEY_CHAR_START {
if let Some(key) = KEY_MAP.get(&key) { pub extern "C" fn fix_key_down_timeout_at_exit() {
Some(*key) let mut exiting = EXITING.lock().unwrap();
} else { if *exiting {
None return;
} }
*exiting = true;
fix_key_down_timeout(true);
log::info!("fix_key_down_timeout_at_exit");
}
extern "C" fn fix_key_down_timeout_at_signal(_: libc::c_int) {
fix_key_down_timeout_at_exit();
std::process::exit(0); // will call atexit on posix, but not on Windows
}
fn fix_key_down_timeout(force: bool) {
if KEYS_DOWN.lock().unwrap().is_empty() {
return;
}
let cloned = (*KEYS_DOWN.lock().unwrap()).clone();
log::debug!("{} keys in key down timeout map", cloned.len());
for (key, value) in cloned.into_iter() {
if force || value.elapsed().as_millis() >= 3_000 {
KEYS_DOWN.lock().unwrap().remove(&key);
let key = if key < KEY_CHAR_START {
if let Some(key) = KEY_MAP.get(&key) {
Some(*key)
} else { } else {
Some(Key::Layout(((key - KEY_CHAR_START) as u8) as _)) None
};
if let Some(key) = key {
let func = move || {
let mut en = ENIGO.lock().unwrap();
if en.get_key_state(key) {
en.key_up(key);
log::debug!("Fixed {:?} timeout", key);
}
};
#[cfg(target_os = "macos")]
QUEUE.exec_async(func);
#[cfg(not(target_os = "macos"))]
func();
} }
} else {
Some(Key::Layout(((key - KEY_CHAR_START) as u8) as _))
};
if let Some(key) = key {
let func = move || {
let mut en = ENIGO.lock().unwrap();
if en.get_key_state(key) {
en.key_up(key);
log::debug!("Fixed {:?} timeout", key);
}
};
#[cfg(target_os = "macos")]
QUEUE.exec_async(func);
#[cfg(not(target_os = "macos"))]
func();
} }
} }
}); }
} }
// e.g. current state of ctrl is down, but ctrl not in modifier, we should change ctrl to up, to make modifier state sync between remote and local // e.g. current state of ctrl is down, but ctrl not in modifier, we should change ctrl to up, to make modifier state sync between remote and local
@ -292,6 +317,10 @@ fn fix_modifiers(modifiers: &[ProtobufEnumOrUnknown<ControlKey>], en: &mut Enigo
} }
fn handle_mouse_(evt: &MouseEvent, conn: i32) { fn handle_mouse_(evt: &MouseEvent, conn: i32) {
let exiting = EXITING.lock().unwrap();
if *exiting {
return;
}
#[cfg(windows)] #[cfg(windows)]
crate::platform::windows::try_change_desktop(); crate::platform::windows::try_change_desktop();
let buttons = evt.mask >> 3; let buttons = evt.mask >> 3;
@ -496,6 +525,10 @@ pub fn handle_key(evt: &KeyEvent) {
} }
fn handle_key_(evt: &KeyEvent) { fn handle_key_(evt: &KeyEvent) {
let exiting = EXITING.lock().unwrap();
if *exiting {
return;
}
#[cfg(windows)] #[cfg(windows)]
crate::platform::windows::try_change_desktop(); crate::platform::windows::try_change_desktop();
let mut en = ENIGO.lock().unwrap(); let mut en = ENIGO.lock().unwrap();