From fb2d2bc2865beeb49a49337fcfe12654cd013ffc Mon Sep 17 00:00:00 2001 From: Oussama Teffahi <70609372+oteffahi@users.noreply.github.com> Date: Tue, 10 Dec 2024 17:09:22 +0100 Subject: [PATCH] Fix deadlock in subscriber undeclaration (#1649) * Fix deadlock * Only update matching listener status for last remote subscriber * Remove unnecessary drop after changes * Add unit test for undeclare deadlock --- zenoh/src/api/session.rs | 30 ++++++++++++++++++++---------- zenoh/tests/session.rs | 12 ++++++++++++ 2 files changed, 32 insertions(+), 10 deletions(-) diff --git a/zenoh/src/api/session.rs b/zenoh/src/api/session.rs index 15b7fb4d7b..013536e540 100644 --- a/zenoh/src/api/session.rs +++ b/zenoh/src/api/session.rs @@ -1574,19 +1574,29 @@ impl SessionInner { }, }), }); + #[cfg(feature = "unstable")] + { + let state = zread!(self.state); + self.update_matching_status( + &state, + &sub_state.key_expr, + MatchingStatusType::Subscribers, + false, + ) + } } } else { drop(state); - } - #[cfg(feature = "unstable")] - { - let state = zread!(self.state); - self.update_matching_status( - &state, - &sub_state.key_expr, - MatchingStatusType::Subscribers, - false, - ) + #[cfg(feature = "unstable")] + { + let state = zread!(self.state); + self.update_matching_status( + &state, + &sub_state.key_expr, + MatchingStatusType::Subscribers, + false, + ) + } } } SubscriberKind::LivelinessSubscriber => { diff --git a/zenoh/tests/session.rs b/zenoh/tests/session.rs index 3e84249b82..5a18378446 100644 --- a/zenoh/tests/session.rs +++ b/zenoh/tests/session.rs @@ -430,3 +430,15 @@ async fn zenoh_session_close_in_background() { }; ztimeout!(close_all); } + +#[cfg(feature = "unstable")] +#[tokio::test(flavor = "multi_thread", worker_threads = 4)] +async fn test_undeclare_subscribers_same_keyexpr() { + let key_expr = "test/undeclare/subscribers"; + let session = zenoh::open(zenoh::Config::default()).await.unwrap(); + let sub1 = session.declare_subscriber(key_expr).await.unwrap(); + let sub2 = session.declare_subscriber(key_expr).await.unwrap(); + tokio::time::sleep(SLEEP).await; + ztimeout!(sub1.undeclare()).unwrap(); + ztimeout!(sub2.undeclare()).unwrap(); +}