diff --git a/src/hbbs_http/sync.rs b/src/hbbs_http/sync.rs index cd7f95208..251436aa7 100644 --- a/src/hbbs_http/sync.rs +++ b/src/hbbs_http/sync.rs @@ -1,13 +1,13 @@ use std::{collections::HashMap, sync::Mutex, time::Duration}; +#[cfg(not(any(target_os = "ios")))] +use crate::Connection; use hbb_common::{ config::{Config, LocalConfig}, tokio::{self, sync::broadcast, time::Instant}, }; use serde::{Deserialize, Serialize}; use serde_json::{json, Value}; -#[cfg(not(any(target_os = "ios")))] -use crate::Connection; const TIME_HEARTBEAT: Duration = Duration::from_secs(30); const TIME_CONN: Duration = Duration::from_secs(3); @@ -36,7 +36,9 @@ fn start_hbbs_sync() -> broadcast::Sender> { #[derive(Debug, Serialize, Deserialize)] pub struct StrategyOptions { + #[serde(default, skip_serializing_if = "HashMap::is_empty")] pub config_options: HashMap, + #[serde(default, skip_serializing_if = "HashMap::is_empty")] pub extra: HashMap, } diff --git a/src/server/connection.rs b/src/server/connection.rs index 056eaefc3..3a82a6594 100644 --- a/src/server/connection.rs +++ b/src/server/connection.rs @@ -241,12 +241,12 @@ impl Connection { id: i32, server: super::ServerPtrWeak, ) { + let _raii_id = raii::ConnectionID::new(id); let hash = Hash { salt: Config::get_salt(), challenge: Config::get_auto_password(6), ..Default::default() }; - ALIVE_CONNS.lock().unwrap().push(id); let (tx_from_cm_holder, mut rx_from_cm) = mpsc::unbounded_channel::(); // holding tx_from_cm_holder to avoid cpu burning of rx_from_cm.recv when all sender closed let tx_from_cm = tx_from_cm_holder.clone(); @@ -627,22 +627,12 @@ impl Connection { conn.post_conn_audit(json!({ "action": "close", })); - let mut active_conns_lock = ALIVE_CONNS.lock().unwrap(); - active_conns_lock.retain(|&c| c != id); if let Some(s) = conn.server.upgrade() { let mut s = s.write().unwrap(); s.remove_connection(&conn.inner); #[cfg(not(any(target_os = "android", target_os = "ios")))] try_stop_record_cursor_pos(); } - #[cfg(not(any(target_os = "android", target_os = "ios")))] - if active_conns_lock.is_empty() { - video_service::reset_resolutions(); - } - #[cfg(all(windows, feature = "virtual_display_driver"))] - if active_conns_lock.is_empty() { - video_service::try_plug_out_virtual_display(); - } log::info!("#{} connection loop exited", id); } @@ -2538,3 +2528,30 @@ impl Drop for Connection { self.release_pressed_modifiers(); } } + +mod raii { + use super::*; + pub struct ConnectionID(i32); + + impl ConnectionID { + pub fn new(id: i32) -> Self { + ALIVE_CONNS.lock().unwrap().push(id); + Self(id) + } + } + + impl Drop for ConnectionID { + fn drop(&mut self) { + let mut active_conns_lock = ALIVE_CONNS.lock().unwrap(); + active_conns_lock.retain(|&c| c != self.0); + #[cfg(not(any(target_os = "android", target_os = "ios")))] + if active_conns_lock.is_empty() { + video_service::reset_resolutions(); + } + #[cfg(all(windows, feature = "virtual_display_driver"))] + if active_conns_lock.is_empty() { + video_service::try_plug_out_virtual_display(); + } + } + } +}