From 34789c6563f3102e0ef8fb525ac06694246d87bb Mon Sep 17 00:00:00 2001 From: crop Date: Sun, 11 May 2025 15:04:55 +0200 Subject: [PATCH] fix deadlock issue #219 --- src/client/async_client.rs | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/src/client/async_client.rs b/src/client/async_client.rs index fc5566510..b1c086f2b 100644 --- a/src/client/async_client.rs +++ b/src/client/async_client.rs @@ -96,32 +96,30 @@ impl AsyncClient { /// therefore unsafe to continue using. pub fn deactivate(self) -> Result<(Client, N, P), Error> { let mut c = self; - unsafe { - c.maybe_deactivate() - .map(|c| (c.client, c.notification, c.process)) - } + c.maybe_deactivate() + .map(|c| (c.client, c.notification, c.process)) } // Helper function for deactivating. Any function that calls this should // have ownership of self and no longer use it after this call. - unsafe fn maybe_deactivate(&mut self) -> Result>, Error> { - let _m = CREATE_OR_DESTROY_CLIENT_MUTEX.lock().ok(); + fn maybe_deactivate(&mut self) -> Result>, Error> { + let m = CREATE_OR_DESTROY_CLIENT_MUTEX.lock(); if self.callback.is_none() { + drop(m); return Err(Error::ClientIsNoLongerAlive); } let cb = self.callback.take().ok_or(Error::ClientIsNoLongerAlive)?; - let client_ptr = cb.client.raw(); - // deactivate - if j::jack_deactivate(client_ptr) != 0 { + if unsafe { j::jack_deactivate(cb.client.raw()) } != 0 { + drop(m); return Err(Error::ClientDeactivationError); } // clear the callbacks - clear_callbacks(client_ptr)?; + unsafe { clear_callbacks(cb.client.raw()) }?; // done, take ownership of callback if cb.has_panic.load(std::sync::atomic::Ordering::Relaxed) { - std::mem::forget(cb); + drop(m); return Err(Error::ClientPanicked); } Ok(cb) @@ -132,7 +130,7 @@ impl AsyncClient { impl Drop for AsyncClient { // Deactivate and close the client. fn drop(&mut self) { - let _ = unsafe { self.maybe_deactivate() }; + let _ = self.maybe_deactivate(); } }