Skip to content

Commit

Permalink
Added is_closed method
Browse files Browse the repository at this point in the history
  • Loading branch information
fulmicoton authored and faern committed May 23, 2024
1 parent a1e58a1 commit ccd8228
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 0 deletions.
19 changes: 19 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -312,6 +312,25 @@ impl<T> Sender<T> {
}
}

/// Returns true if the associated Receiver handle has been dropped.
///
/// If true is returned, a future call to send is guaranteed to return an error.
pub fn is_closed(&self) -> bool {
// SAFETY: Since we are holding a Sender's reference, we know that:
// - `send(..)` has not been called yet
// - `Sender` has not been dropped.
//
// This is sufficient to guarantee that the channel is still on the heap.
//
// Note that if the receiver disconnects it does not free the channel.
let channel = unsafe { self.channel_ptr.as_ref() };

// ORDERING: We *chose* a Relaxed ordering here as it sufficient to
// enforce the method's contract: "if true is returned, a future
// call to send is guaranteed to return an error."
channel.state.load(Relaxed) == DISCONNECTED
}

/// Consumes the Sender, returning a raw pointer to the channel on the heap.
///
/// This is intended to simplify using oneshot channels with some FFI code. The only safe thing
Expand Down
10 changes: 10 additions & 0 deletions tests/sync.rs
Original file line number Diff line number Diff line change
Expand Up @@ -343,3 +343,13 @@ fn send_error_drops_message_correctly_on_into_inner() {
assert_eq!(counter.count(), 1);
});
}

#[test]
fn dropping_receiver_disconnects_sender() {
maybe_loom_model(|| {
let (sender, receiver) = oneshot::channel::<()>();
assert!(!sender.is_closed());
drop(receiver);
assert!(sender.is_closed());
});
}

0 comments on commit ccd8228

Please sign in to comment.