diff --git a/plugins/zenoh-plugin-example/Cargo.toml b/plugins/zenoh-plugin-example/Cargo.toml index 360df96c3a..6d49826238 100644 --- a/plugins/zenoh-plugin-example/Cargo.toml +++ b/plugins/zenoh-plugin-example/Cargo.toml @@ -42,7 +42,7 @@ futures = { workspace = true } git-version = { workspace = true } log = { workspace = true } serde_json = { workspace = true } -zenoh = { workspace = true } +zenoh = { workspace = true, features = ["unstable"] } zenoh-core = { workspace = true } zenoh-plugin-trait = { workspace = true } zenoh-result = { workspace = true } diff --git a/zenoh/src/handlers.rs b/zenoh/src/handlers.rs index 5efc2e4781..69828a5d7f 100644 --- a/zenoh/src/handlers.rs +++ b/zenoh/src/handlers.rs @@ -86,3 +86,41 @@ pub fn locked(fnmut: impl FnMut(T)) -> impl Fn(T) { let lock = std::sync::Mutex::new(fnmut); move |x| zlock!(lock)(x) } + +/// A handler containing 2 callback functions: +/// - `callback`: the typical callback function. `context` will be passed as its last argument. +/// - `drop`: a callback called when this handler is dropped. +/// +/// It is guaranteed that: +/// +/// - `callback` will never be called once `drop` has started. +/// - `drop` will only be called **once**, and **after every** `callback` has ended. +/// - The two previous guarantees imply that `call` and `drop` are never called concurrently. +pub struct CallbackPair +where + DropFn: FnMut() + Send + Sync + 'static, +{ + pub callback: Callback, + pub drop: DropFn, +} + +impl Drop for CallbackPair +where + DropFn: FnMut() + Send + Sync + 'static, +{ + fn drop(&mut self) { + (self.drop)() + } +} + +impl<'a, OnEvent, Event, DropFn> IntoCallbackReceiverPair<'a, Event> + for CallbackPair +where + OnEvent: Fn(Event) + Send + Sync + 'a, + DropFn: FnMut() + Send + Sync + 'static, +{ + type Receiver = (); + fn into_cb_receiver_pair(self) -> (Callback<'a, Event>, Self::Receiver) { + (Dyn::from(move |evt| (self.callback)(evt)), ()) + } +}