@@ -11,7 +11,8 @@ use crate::core::connection_settings::{
1111 get_saved_connection_path, has_saved_connection, list_saved_connections,
1212} ;
1313use crate :: core:: device:: {
14- list_bluetooth_devices, list_devices, set_wifi_enabled, wait_for_wifi_ready, wifi_enabled,
14+ is_connecting, list_bluetooth_devices, list_devices, set_wifi_enabled, wait_for_wifi_ready,
15+ wifi_enabled,
1516} ;
1617use crate :: core:: scan:: { current_network, list_networks, scan_networks} ;
1718use crate :: core:: vpn:: { connect_vpn, disconnect_vpn, get_vpn_info, list_vpn_connections} ;
@@ -114,6 +115,14 @@ use crate::Result;
114115///
115116/// `NetworkManager` is `Clone` and can be safely shared across async tasks.
116117/// Each clone shares the same underlying D-Bus connection.
118+ ///
119+ /// # Concurrency
120+ ///
121+ /// Concurrent connection operations (e.g. calling [`connect`](Self::connect)
122+ /// from multiple tasks simultaneously) are **not supported** and may cause
123+ /// race conditions. Use [`is_connecting`](Self::is_connecting) to check
124+ /// whether a connection operation is already in progress before starting
125+ /// a new one.
117126#[ derive( Debug , Clone ) ]
118127pub struct NetworkManager {
119128 conn : Connection ,
@@ -425,6 +434,32 @@ impl NetworkManager {
425434 scan_networks ( & self . conn ) . await
426435 }
427436
437+ /// Returns whether any network device is currently in a transitional state.
438+ ///
439+ /// A device is considered "connecting" when its state is one of:
440+ /// Prepare, Config, NeedAuth, IpConfig, IpCheck, Secondaries, or Deactivating.
441+ ///
442+ /// Use this to guard against concurrent connection attempts, which are
443+ /// not supported and may cause undefined behavior.
444+ ///
445+ /// # Example
446+ ///
447+ /// ```no_run
448+ /// use nmrs::NetworkManager;
449+ ///
450+ /// # async fn example() -> nmrs::Result<()> {
451+ /// let nm = NetworkManager::new().await?;
452+ ///
453+ /// if nm.is_connecting().await? {
454+ /// eprintln!("A connection operation is already in progress");
455+ /// }
456+ /// # Ok(())
457+ /// # }
458+ /// ```
459+ pub async fn is_connecting ( & self ) -> Result < bool > {
460+ is_connecting ( & self . conn ) . await
461+ }
462+
428463 /// Check if a network is connected
429464 pub async fn is_connected ( & self , ssid : & str ) -> Result < bool > {
430465 is_connected ( & self . conn , ssid) . await
0 commit comments