Skip to content

Commit

Permalink
refactor: drop LazyConnection
Browse files Browse the repository at this point in the history
  • Loading branch information
SeaDve committed Sep 17, 2023
1 parent 6b9da1f commit 1f19a8c
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 45 deletions.
12 changes: 5 additions & 7 deletions src/local_server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ use std::{
marker::PhantomData,
pin::Pin,
rc::Rc,
sync::Arc,
task::{Context, Poll},
};

Expand Down Expand Up @@ -527,7 +526,7 @@ pub struct LocalServer<T>
where
T: LocalPlayerInterface + 'static,
{
inner: Server<InnerImp<T>>,
inner: Rc<Server<InnerImp<T>>>,
imp: Rc<T>,
runner: RefCell<Option<TaskInner>>,
}
Expand Down Expand Up @@ -813,21 +812,20 @@ where
{
let (tx, rx) = mpsc::unbounded::<Action>();

let inner = server_func(
let inner = Rc::new(server_func(
bus_name_suffix,
InnerImp {
tx,
imp_ty: PhantomData,
},
)?;
)?);

let imp = Rc::new(imp);

let connection = Arc::clone(&inner.connection);
let inner_clone = Rc::clone(&inner);
let imp_clone = Rc::clone(&imp);
let runner = Box::pin(async move {
// Initialize the connection
connection.get().await?;
inner_clone.init().await?;
runner_func(rx, imp_clone).await;
Ok(())
});
Expand Down
60 changes: 22 additions & 38 deletions src/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -345,37 +345,6 @@ where
}
}

pub(crate) struct LazyConnection {
connection: OnceCell<Connection>,
#[allow(clippy::type_complexity)]
connection_init:
Mutex<Option<Box<dyn FnOnce() -> Result<ConnectionBuilder<'static>> + Send + Sync>>>,
}

impl LazyConnection {
fn new(
init_func: impl FnOnce() -> Result<ConnectionBuilder<'static>> + Send + Sync + 'static,
) -> Self {
Self {
connection: OnceCell::new(),
connection_init: Mutex::new(Some(Box::new(init_func))),
}
}

/// Returns a reference to the underlying [`Connection`], initializing it if
/// it has not been initialized yet.
pub(crate) async fn get(&self) -> Result<&Connection> {
self.connection
.get_or_try_init(|| async {
// Safety: connection only initialized once
let connection_init = self.connection_init.lock().unwrap().take().unwrap();
let connection = connection_init()?.build().await?;
Ok(connection)
})
.await
}
}

/// Thin wrapper around [`zbus::Connection`] that calls to `T`'s implementation
/// of [`RootInterface`], [`PlayerInterface`], [`TrackListInterface`], and
/// [`PlaylistsInterface`] to implement `org.mpris.MediaPlayer2` and its
Expand All @@ -390,7 +359,10 @@ pub struct Server<T>
where
T: PlayerInterface + 'static,
{
pub(crate) connection: Arc<LazyConnection>,
connection: OnceCell<Connection>,
#[allow(clippy::type_complexity)]
connection_init:
Mutex<Option<Box<dyn FnOnce() -> Result<ConnectionBuilder<'static>> + Send + Sync>>>,
imp: Arc<T>,
}

Expand Down Expand Up @@ -449,7 +421,7 @@ where
/// This is also called automatically when emitting signals and properties
/// changed.
pub async fn init(&self) -> Result<()> {
self.connection.get().await?;
self.get_or_init_connection().await?;
Ok(())
}

Expand All @@ -462,7 +434,7 @@ where
///
/// If you needed to call this, consider filing an issue.
pub async fn connection(&self) -> Result<&Connection> {
self.connection.get().await
self.get_or_init_connection().await
}

/// Emits the given signal.
Expand Down Expand Up @@ -547,7 +519,7 @@ where
let imp = Arc::new(imp);

let imp_clone = Arc::clone(&imp);
let connection_init = || {
let connection_init = Box::new(|| {
let builder = ConnectionBuilder::session()?
.name(bus_name)?
.serve_at(
Expand All @@ -563,14 +535,26 @@ where
},
)?;
builder_ext_func(builder, imp_clone)
};
});

Ok(Self {
connection: Arc::new(LazyConnection::new(connection_init)),
connection: OnceCell::new(),
connection_init: Mutex::new(Some(connection_init)),
imp,
})
}

async fn get_or_init_connection(&self) -> Result<&Connection> {
self.connection
.get_or_try_init(|| async {
// Safety: connection only initialized once
let connection_init = self.connection_init.lock().unwrap().take().unwrap();
let connection = connection_init()?.build().await?;
Ok(connection)
})
.await
}

async fn properties_changed_inner<I>(
&self,
changed_properties: HashMap<&str, Value<'_>>,
Expand All @@ -594,7 +578,7 @@ where
where
I: Interface,
{
let connection = self.connection.get().await?;
let connection = self.get_or_init_connection().await?;

// FIXME Hold a lock to the interface until the signal is emitted.
// This is a workaround for `Invalid client serial` errors.
Expand Down

0 comments on commit 1f19a8c

Please sign in to comment.