From 6de20e818f7ed9b4d24458cb2ae7249cfe82b49c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sosth=C3=A8ne=20Gu=C3=A9don?= Date: Thu, 7 May 2026 16:58:32 +0200 Subject: [PATCH 1/2] Fix new lints --- src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib.rs b/src/lib.rs index 3f062ae..b650bfd 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -901,7 +901,7 @@ impl Interchange { } /// Claim one of the channels of the interchange. Returns None if called more than `N` times. - pub fn claim(&self) -> Option<(Requester, Responder)> { + pub fn claim(&'_ self) -> Option<(Requester<'_, Rq, Rp>, Responder<'_, Rq, Rp>)> { self.as_interchange_ref().claim() } From 3dd20626c26627f58dbbf25dc0359a00916b7a0e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sosth=C3=A8ne=20Gu=C3=A9don?= Date: Thu, 7 May 2026 16:59:16 +0200 Subject: [PATCH 2/2] Add callback mechanism --- src/lib.rs | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index b650bfd..69d4699 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -171,6 +171,9 @@ impl From for State { } } +/// Callback that can be called +pub type Callback = fn(); + // the repr(u8) is necessary so MaybeUninit::zeroized.assume_init() is valid and corresponds to // None #[repr(u8)] @@ -361,7 +364,10 @@ impl Channel { .compare_exchange(false, true, Ordering::Relaxed, Ordering::Relaxed) .is_ok() { - Some(Requester { channel: self }) + Some(Requester { + channel: self, + callback: || {}, + }) } else { None } @@ -376,7 +382,10 @@ impl Channel { .compare_exchange(false, true, Ordering::Relaxed, Ordering::Relaxed) .is_ok() { - Some(Responder { channel: self }) + Some(Responder { + channel: self, + callback: || {}, + }) } else { None } @@ -408,6 +417,7 @@ impl Default for Channel { /// the requester uses a `'static` lifetime parameter pub struct Requester<'i, Rq, Rp> { channel: &'i Channel, + callback: Callback, } impl Drop for Requester<'_, Rq, Rp> { @@ -419,6 +429,10 @@ impl Drop for Requester<'_, Rq, Rp> { } impl<'i, Rq, Rp> Requester<'i, Rq, Rp> { + pub fn callback_mut(&mut self) -> &mut Callback { + &mut self.callback + } + pub fn channel(&self) -> &'i Channel { self.channel } @@ -479,6 +493,7 @@ impl<'i, Rq, Rp> Requester<'i, Rq, Rp> { self.channel .state .store(State::Requested as u8, Ordering::Release); + (self.callback)(); Ok(()) } else { Err(Error) @@ -503,6 +518,7 @@ impl<'i, Rq, Rp> Requester<'i, Rq, Rp> { } if self.channel.transition(State::Requested, State::Idle) { + (self.callback)(); // we canceled before the responder was even aware of the request. return Ok(Some(unsafe { self.with_data_mut(|i| i.take_rq()) })); } @@ -611,6 +627,7 @@ where .channel .transition(State::BuildingRequest, State::Requested) { + (self.callback)(); Ok(()) } else { // logic error @@ -625,6 +642,7 @@ where /// the responder uses a `'static` lifetime parameter pub struct Responder<'i, Rq, Rp> { channel: &'i Channel, + callback: Callback, } impl Drop for Responder<'_, Rq, Rp> { @@ -636,6 +654,10 @@ impl Drop for Responder<'_, Rq, Rp> { } impl<'i, Rq, Rp> Responder<'i, Rq, Rp> { + pub fn callback_mut(&mut self) -> &mut Callback { + &mut self.callback + } + pub fn channel(&self) -> &'i Channel { self.channel } @@ -758,6 +780,7 @@ impl<'i, Rq, Rp> Responder<'i, Rq, Rp> { .channel .transition(State::BuildingResponse, State::Responded) { + (self.callback)(); Ok(()) } else { Err(Error) @@ -832,6 +855,7 @@ where .channel .transition(State::BuildingResponse, State::Responded) { + (self.callback)(); Ok(()) } else { // logic error