Remove KEYBOARD_HOOKED unsafe code, by using AtomicBool

For supported types, static R/W globals unsafe code can be replaced by safe `Atomic*` types.

The pattern of usage is simple:

- AtomicBool#swap is used to fetch the old `KEYBOARD_HOOKED` value, while setting it to true;
- if the old value was true, there is effectively no change to `KEYBOARD_HOOKED`, and the flow exits from the enclosing function;
- if the old value was false, execute the function (the new `KEYBOARD_HOOKED` has been set to true by swap()).

The most conservative ordering is used, as the context is not performance-sensitive.

Atomics are not supported on every platform, but the project assumes x86-64, which supports them.
This commit is contained in:
Saverio Miroddi 2022-05-22 18:03:38 +02:00
parent 8e2aaf578f
commit 7f50fe3ea0

View File

@ -1,7 +1,10 @@
use std::{
collections::HashMap,
ops::Deref,
sync::{Arc, Mutex, RwLock},
sync::{
atomic::{AtomicBool, Ordering},
Arc, Mutex, RwLock,
},
};
use sciter::{
@ -64,7 +67,7 @@ fn get_key_state(key: enigo::Key) -> bool {
}
static mut IS_IN: bool = false;
static mut KEYBOARD_HOOKED: bool = false;
static KEYBOARD_HOOKED: AtomicBool = AtomicBool::new(false);
static mut SERVER_KEYBOARD_ENABLED: bool = true;
static mut SERVER_FILE_TRANSFER_ENABLED: bool = true;
static mut SERVER_CLIPBOARD_ENABLED: bool = true;
@ -249,12 +252,9 @@ impl Handler {
if self.is_port_forward() || self.is_file_transfer() {
return;
}
if unsafe { KEYBOARD_HOOKED } {
if KEYBOARD_HOOKED.swap(true, Ordering::SeqCst) {
return;
}
unsafe {
KEYBOARD_HOOKED = true;
}
log::info!("keyboard hooked");
let mut me = self.clone();
let peer = self.peer_platform();