diff options
Diffstat (limited to '')
-rw-r--r-- | third_party/rust/oneshot-uniffi/src/errors.rs | 15 | ||||
-rw-r--r-- | third_party/rust/oneshot-uniffi/src/lib.rs | 51 |
2 files changed, 59 insertions, 7 deletions
diff --git a/third_party/rust/oneshot-uniffi/src/errors.rs b/third_party/rust/oneshot-uniffi/src/errors.rs index afc48acd03..1fd0de1eed 100644 --- a/third_party/rust/oneshot-uniffi/src/errors.rs +++ b/third_party/rust/oneshot-uniffi/src/errors.rs @@ -4,7 +4,8 @@ use core::mem; use core::ptr::NonNull; /// An error returned when trying to send on a closed channel. Returned from -/// [`Sender::send`] if the corresponding [`Receiver`] has already been dropped. +/// [`Sender::send`](crate::Sender::send) if the corresponding [`Receiver`](crate::Receiver) +/// has already been dropped. /// /// The message that could not be sent can be retreived again with [`SendError::into_inner`]. pub struct SendError<T> { @@ -79,10 +80,10 @@ impl<T> fmt::Debug for SendError<T> { #[cfg(feature = "std")] impl<T> std::error::Error for SendError<T> {} -/// An error returned from the indefinitely blocking recv functions on a [`Receiver`]. +/// An error returned from the blocking [`Receiver::recv`](crate::Receiver::recv) method. /// -/// The recv operation can only fail if the corresponding [`Sender`] was dropped before sending -/// any message. Or if a message has already been sent and received on the channel. +/// The receive operation can only fail if the corresponding [`Sender`](crate::Sender) was dropped +/// before sending any message, or if a message has already been sent and received on the channel. #[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] pub struct RecvError; @@ -95,7 +96,8 @@ impl fmt::Display for RecvError { #[cfg(feature = "std")] impl std::error::Error for RecvError {} -/// An error returned when trying a non blocking receive on a [`Receiver`]. +/// An error returned when failing to receive a message in the non-blocking +/// [`Receiver::try_recv`](crate::Receiver::try_recv). #[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] pub enum TryRecvError { /// The channel is still open, but there was no message present in it. @@ -119,7 +121,8 @@ impl fmt::Display for TryRecvError { #[cfg(feature = "std")] impl std::error::Error for TryRecvError {} -/// An error returned when trying a time limited blocking receive on a [`Receiver`]. +/// An error returned when failing to receive a message in +/// [`Receiver::recv_timeout`](crate::Receiver::recv_timeout). #[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] pub enum RecvTimeoutError { /// No message arrived on the channel before the timeout was reached. The channel is still open. diff --git a/third_party/rust/oneshot-uniffi/src/lib.rs b/third_party/rust/oneshot-uniffi/src/lib.rs index 94bb35d12a..8da012b8c0 100644 --- a/third_party/rust/oneshot-uniffi/src/lib.rs +++ b/third_party/rust/oneshot-uniffi/src/lib.rs @@ -314,6 +314,31 @@ impl<T> Sender<T> { _ => unreachable!(), } } + + /// 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 + /// to do with the returned pointer is to later reconstruct the Sender with [Sender::from_raw]. + /// Memory will leak if the Sender is never reconstructed. + pub fn into_raw(self) -> *mut () { + let raw = self.channel_ptr.as_ptr() as *mut (); + mem::forget(self); + raw + } + + /// Consumes a raw pointer from [Sender::into_raw], recreating the Sender. + /// + /// # Safety + /// + /// This pointer must have come from [`Sender<T>::into_raw`] with the same message type, `T`. + /// At most one Sender must exist for a channel at any point in time. + /// Constructing multiple Senders from the same raw pointer leads to undefined behavior. + pub unsafe fn from_raw(raw: *mut ()) -> Self { + Self { + channel_ptr: NonNull::new_unchecked(raw as *mut Channel<T>), + _invariant: PhantomData, + } + } } impl<T> Drop for Sender<T> { @@ -816,6 +841,30 @@ impl<T> Receiver<T> { _ => unreachable!(), } } + + /// Consumes the Receiver, 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 + /// to do with the returned pointer is to later reconstruct the Receiver with + /// [Receiver::from_raw]. Memory will leak if the Receiver is never reconstructed. + pub fn into_raw(self) -> *mut () { + let raw = self.channel_ptr.as_ptr() as *mut (); + mem::forget(self); + raw + } + + /// Consumes a raw pointer from [Receiver::into_raw], recreating the Receiver. + /// + /// # Safety + /// + /// This pointer must have come from [`Receiver<T>::into_raw`] with the same message type, `T`. + /// At most one Receiver must exist for a channel at any point in time. + /// Constructing multiple Receivers from the same raw pointer leads to undefined behavior. + pub unsafe fn from_raw(raw: *mut ()) -> Self { + Self { + channel_ptr: NonNull::new_unchecked(raw as *mut Channel<T>), + } + } } #[cfg(feature = "async")] @@ -1178,7 +1227,7 @@ fn receiver_waker_size() { (false, false) => 0, (false, true) => 16, (true, false) => 8, - (true, true) => 24, + (true, true) => 16, }; assert_eq!(mem::size_of::<ReceiverWaker>(), expected); } |