Skip to content

Commit

Permalink
Merge pull request #664 from imobachgs/async-aware-mutex
Browse files Browse the repository at this point in the history
Use an async-aware Mutex implementation
  • Loading branch information
imobachgs authored Aug 14, 2023
2 parents ff4b61c + 33195b2 commit f86969b
Show file tree
Hide file tree
Showing 5 changed files with 73 additions and 72 deletions.
2 changes: 1 addition & 1 deletion rust/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions rust/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@ members = [
"agama-locale-data",
"agama-settings"
]

4 changes: 2 additions & 2 deletions rust/agama-dbus-server/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ zbus = "3.7.0"
zbus_macros = "3.7.0"
async-std = { version = "1.12.0", features = ["attributes"]}
uuid = { version = "1.3.4", features = ["v4"] }
parking_lot = "0.12.1"
thiserror = "1.0.40"
serde = { version = "1.0.152", features = ["derive"] }
serde_yaml = "0.9.24"
serde_yaml = "0.9.24"
futures = "0.3.28"
126 changes: 63 additions & 63 deletions rust/agama-dbus-server/src/network/dbus/interfaces.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use crate::network::{
use log;

use agama_lib::network::types::SSID;
use parking_lot::{MappedMutexGuard, Mutex, MutexGuard};
use futures::lock::{MappedMutexGuard, Mutex, MutexGuard};
use std::{
net::{AddrParseError, Ipv4Addr},
sync::{mpsc::Sender, Arc},
Expand Down Expand Up @@ -42,8 +42,8 @@ impl Devices {
#[dbus_interface(name = "org.opensuse.Agama.Network1.Devices")]
impl Devices {
/// Returns the D-Bus paths of the network devices.
pub fn get_devices(&self) -> Vec<ObjectPath> {
let objects = self.objects.lock();
pub async fn get_devices(&self) -> Vec<ObjectPath> {
let objects = self.objects.lock().await;
objects
.devices_paths()
.iter()
Expand Down Expand Up @@ -112,8 +112,8 @@ impl Connections {
#[dbus_interface(name = "org.opensuse.Agama.Network1.Connections")]
impl Connections {
/// Returns the D-Bus paths of the network connections.
pub fn get_connections(&self) -> Vec<ObjectPath> {
let objects = self.objects.lock();
pub async fn get_connections(&self) -> Vec<ObjectPath> {
let objects = self.objects.lock().await;
objects
.connections_paths()
.iter()
Expand All @@ -126,7 +126,7 @@ impl Connections {
/// * `id`: connection name.
/// * `ty`: connection type (see [agama_lib::network::types::DeviceType]).
pub async fn add_connection(&mut self, id: String, ty: u8) -> zbus::fdo::Result<()> {
let actions = self.actions.lock();
let actions = self.actions.lock().await;
actions
.send(Action::AddConnection(id, ty.try_into()?))
.unwrap();
Expand All @@ -137,7 +137,7 @@ impl Connections {
///
/// * `id`: connection ID.
pub async fn get_connection(&self, id: &str) -> zbus::fdo::Result<OwnedObjectPath> {
let objects = self.objects.lock();
let objects = self.objects.lock().await;
match objects.connection_path(id) {
Some(path) => Ok(path.into()),
None => Err(NetworkStateError::UnknownConnection(id.to_string()).into()),
Expand All @@ -148,7 +148,7 @@ impl Connections {
///
/// * `uuid`: connection UUID..
pub async fn remove_connection(&mut self, id: &str) -> zbus::fdo::Result<()> {
let actions = self.actions.lock();
let actions = self.actions.lock().await;
actions
.send(Action::RemoveConnection(id.to_string()))
.unwrap();
Expand All @@ -159,7 +159,7 @@ impl Connections {
///
/// It includes adding, updating and removing connections as needed.
pub async fn apply(&self) -> zbus::fdo::Result<()> {
let actions = self.actions.lock();
let actions = self.actions.lock().await;
actions.send(Action::Apply).unwrap();
Ok(())
}
Expand All @@ -181,8 +181,8 @@ impl Connection {
}

/// Returns the underlying connection.
fn get_connection(&self) -> MutexGuard<NetworkConnection> {
self.connection.lock()
async fn get_connection(&self) -> MutexGuard<NetworkConnection> {
self.connection.lock().await
}
}

Expand All @@ -194,8 +194,8 @@ impl Connection {
/// backend. For instance, when using NetworkManager (which is the only supported backend by
/// now), it uses the original ID but appending a number in case the ID is duplicated.
#[dbus_interface(property)]
pub fn id(&self) -> String {
self.get_connection().id().to_string()
pub async fn id(&self) -> String {
self.get_connection().await.id().to_string()
}
}

Expand All @@ -218,18 +218,18 @@ impl Ipv4 {
}

/// Returns the underlying connection.
fn get_connection(&self) -> MutexGuard<NetworkConnection> {
self.connection.lock()
async fn get_connection(&self) -> MutexGuard<NetworkConnection> {
self.connection.lock().await
}

/// Updates the connection data in the NetworkSystem.
///
/// * `connection`: Updated connection.
fn update_connection(
async fn update_connection<'a>(
&self,
connection: MutexGuard<NetworkConnection>,
connection: MutexGuard<'a, NetworkConnection>,
) -> zbus::fdo::Result<()> {
let actions = self.actions.lock();
let actions = self.actions.lock().await;
actions
.send(Action::UpdateConnection(connection.clone()))
.unwrap();
Expand All @@ -243,8 +243,8 @@ impl Ipv4 {
///
/// When the method is 'auto', these addresses are used as additional addresses.
#[dbus_interface(property)]
pub fn addresses(&self) -> Vec<String> {
let connection = self.get_connection();
pub async fn addresses(&self) -> Vec<String> {
let connection = self.get_connection().await;
connection
.ipv4()
.addresses
Expand All @@ -254,8 +254,8 @@ impl Ipv4 {
}

#[dbus_interface(property)]
pub fn set_addresses(&mut self, addresses: Vec<String>) -> zbus::fdo::Result<()> {
let mut connection = self.get_connection();
pub async fn set_addresses(&mut self, addresses: Vec<String>) -> zbus::fdo::Result<()> {
let mut connection = self.get_connection().await;
let parsed: Vec<IpAddress> = addresses
.into_iter()
.filter_map(|ip| match ip.parse::<IpAddress>() {
Expand All @@ -267,7 +267,7 @@ impl Ipv4 {
})
.collect();
connection.ipv4_mut().addresses = parsed;
self.update_connection(connection)
self.update_connection(connection).await
}

/// IP configuration method.
Expand All @@ -276,22 +276,22 @@ impl Ipv4 {
///
/// See [crate::network::model::IpMethod].
#[dbus_interface(property)]
pub fn method(&self) -> String {
let connection = self.get_connection();
pub async fn method(&self) -> String {
let connection = self.get_connection().await;
connection.ipv4().method.to_string()
}

#[dbus_interface(property)]
pub fn set_method(&mut self, method: &str) -> zbus::fdo::Result<()> {
let mut connection = self.get_connection();
pub async fn set_method(&mut self, method: &str) -> zbus::fdo::Result<()> {
let mut connection = self.get_connection().await;
connection.ipv4_mut().method = method.parse()?;
self.update_connection(connection)
self.update_connection(connection).await
}

/// Name server addresses.
#[dbus_interface(property)]
pub fn nameservers(&self) -> Vec<String> {
let connection = self.get_connection();
pub async fn nameservers(&self) -> Vec<String> {
let connection = self.get_connection().await;
connection
.ipv4()
.nameservers
Expand All @@ -301,42 +301,42 @@ impl Ipv4 {
}

#[dbus_interface(property)]
pub fn set_nameservers(&mut self, addresses: Vec<String>) -> zbus::fdo::Result<()> {
let mut connection = self.get_connection();
pub async fn set_nameservers(&mut self, addresses: Vec<String>) -> zbus::fdo::Result<()> {
let mut connection = self.get_connection().await;
let ipv4 = connection.ipv4_mut();
addresses
.iter()
.map(|addr| addr.parse::<Ipv4Addr>())
.collect::<Result<Vec<Ipv4Addr>, AddrParseError>>()
.map(|parsed| ipv4.nameservers = parsed)
.map_err(NetworkStateError::from)?;
self.update_connection(connection)
self.update_connection(connection).await
}

/// Network gateway.
///
/// An empty string removes the current value. It is not possible to set a gateway if the
/// Addresses property is empty.
#[dbus_interface(property)]
pub fn gateway(&self) -> String {
let connection = self.get_connection();
pub async fn gateway(&self) -> String {
let connection = self.get_connection().await;
match connection.ipv4().gateway {
Some(addr) => addr.to_string(),
None => "".to_string(),
}
}

#[dbus_interface(property)]
pub fn set_gateway(&mut self, gateway: String) -> zbus::fdo::Result<()> {
let mut connection = self.get_connection();
pub async fn set_gateway(&mut self, gateway: String) -> zbus::fdo::Result<()> {
let mut connection = self.get_connection().await;
let ipv4 = connection.ipv4_mut();
if gateway.is_empty() {
ipv4.gateway = None;
} else {
let parsed: Ipv4Addr = gateway.parse().map_err(NetworkStateError::from)?;
ipv4.gateway = Some(parsed);
}
self.update_connection(connection)
self.update_connection(connection).await
}
}
/// D-Bus interface for wireless settings
Expand All @@ -360,8 +360,8 @@ impl Wireless {
/// Gets the wireless connection.
///
/// Beware that it crashes when it is not a wireless connection.
fn get_wireless(&self) -> MappedMutexGuard<WirelessConnection> {
MutexGuard::map(self.connection.lock(), |c| match c {
async fn get_wireless(&self) -> MappedMutexGuard<NetworkConnection, WirelessConnection> {
MutexGuard::map(self.connection.lock().await, |c| match c {
NetworkConnection::Wireless(config) => config,
_ => panic!("Not a wireless network. This is most probably a bug."),
})
Expand All @@ -370,11 +370,11 @@ impl Wireless {
/// Updates the connection data in the NetworkSystem.
///
/// * `connection`: Updated connection.
fn update_connection(
async fn update_connection<'a>(
&self,
connection: MappedMutexGuard<WirelessConnection>,
connection: MappedMutexGuard<'a, NetworkConnection, WirelessConnection>,
) -> zbus::fdo::Result<()> {
let actions = self.actions.lock();
let actions = self.actions.lock().await;
let connection = NetworkConnection::Wireless(connection.clone());
actions.send(Action::UpdateConnection(connection)).unwrap();
Ok(())
Expand All @@ -385,16 +385,16 @@ impl Wireless {
impl Wireless {
/// Network SSID.
#[dbus_interface(property, name = "SSID")]
pub fn ssid(&self) -> Vec<u8> {
let connection = self.get_wireless();
pub async fn ssid(&self) -> Vec<u8> {
let connection = self.get_wireless().await;
connection.wireless.ssid.clone().into()
}

#[dbus_interface(property, name = "SSID")]
pub fn set_ssid(&mut self, ssid: Vec<u8>) -> zbus::fdo::Result<()> {
let mut connection = self.get_wireless();
pub async fn set_ssid(&mut self, ssid: Vec<u8>) -> zbus::fdo::Result<()> {
let mut connection = self.get_wireless().await;
connection.wireless.ssid = SSID(ssid);
self.update_connection(connection)
self.update_connection(connection).await
}

/// Wireless connection mode.
Expand All @@ -403,22 +403,22 @@ impl Wireless {
///
/// See [crate::network::model::WirelessMode].
#[dbus_interface(property)]
pub fn mode(&self) -> String {
let connection = self.get_wireless();
pub async fn mode(&self) -> String {
let connection = self.get_wireless().await;
connection.wireless.mode.to_string()
}

#[dbus_interface(property)]
pub fn set_mode(&mut self, mode: &str) -> zbus::fdo::Result<()> {
let mut connection = self.get_wireless();
pub async fn set_mode(&mut self, mode: &str) -> zbus::fdo::Result<()> {
let mut connection = self.get_wireless().await;
connection.wireless.mode = mode.try_into()?;
self.update_connection(connection)
self.update_connection(connection).await
}

/// Password to connect to the wireless network.
#[dbus_interface(property)]
pub fn password(&self) -> String {
let connection = self.get_wireless();
pub async fn password(&self) -> String {
let connection = self.get_wireless().await;
connection
.wireless
.password
Expand All @@ -427,14 +427,14 @@ impl Wireless {
}

#[dbus_interface(property)]
pub fn set_password(&mut self, password: String) -> zbus::fdo::Result<()> {
let mut connection = self.get_wireless();
pub async fn set_password(&mut self, password: String) -> zbus::fdo::Result<()> {
let mut connection = self.get_wireless().await;
connection.wireless.password = if password.is_empty() {
None
} else {
Some(password)
};
self.update_connection(connection)
self.update_connection(connection).await
}

/// Wireless security protocol.
Expand All @@ -444,18 +444,18 @@ impl Wireless {
///
/// See [crate::network::model::SecurityProtocol].
#[dbus_interface(property)]
pub fn security(&self) -> String {
let connection = self.get_wireless();
pub async fn security(&self) -> String {
let connection = self.get_wireless().await;
connection.wireless.security.to_string()
}

#[dbus_interface(property)]
pub fn set_security(&mut self, security: &str) -> zbus::fdo::Result<()> {
let mut connection = self.get_wireless();
pub async fn set_security(&mut self, security: &str) -> zbus::fdo::Result<()> {
let mut connection = self.get_wireless().await;
connection.wireless.security = security
.try_into()
.map_err(|_| NetworkStateError::InvalidSecurityProtocol(security.to_string()))?;
self.update_connection(connection)?;
self.update_connection(connection).await?;
Ok(())
}
}
Loading

0 comments on commit f86969b

Please sign in to comment.