1 use super::{dealloc, Channel}; 2 use core::fmt; 3 use core::mem; 4 use core::ptr::NonNull; 5 6 /// An error returned when trying to send on a closed channel. Returned from 7 /// [`Sender::send`](crate::Sender::send) if the corresponding [`Receiver`](crate::Receiver) 8 /// has already been dropped. 9 /// 10 /// The message that could not be sent can be retreived again with [`SendError::into_inner`]. 11 pub struct SendError<T> { 12 channel_ptr: NonNull<Channel<T>>, 13 } 14 15 unsafe impl<T: Send> Send for SendError<T> {} 16 unsafe impl<T: Sync> Sync for SendError<T> {} 17 18 impl<T> SendError<T> { 19 /// # Safety 20 /// 21 /// By calling this function, the caller semantically transfers ownership of the 22 /// channel's resources to the created `SendError`. Thus the caller must ensure that the 23 /// pointer is not used in a way which would violate this ownership transfer. Moreover, 24 /// the caller must assert that the channel contains a valid, initialized message. new(channel_ptr: NonNull<Channel<T>>) -> Self25 pub(crate) const unsafe fn new(channel_ptr: NonNull<Channel<T>>) -> Self { 26 Self { channel_ptr } 27 } 28 29 /// Consumes the error and returns the message that failed to be sent. 30 #[inline] into_inner(self) -> T31 pub fn into_inner(self) -> T { 32 let channel_ptr = self.channel_ptr; 33 34 // Don't run destructor if we consumed ourselves. Freeing happens here. 35 mem::forget(self); 36 37 // SAFETY: we have ownership of the channel 38 let channel: &Channel<T> = unsafe { channel_ptr.as_ref() }; 39 40 // SAFETY: we know that the message is initialized according to the safety requirements of 41 // `new` 42 let message = unsafe { channel.take_message() }; 43 44 // SAFETY: we own the channel 45 unsafe { dealloc(channel_ptr) }; 46 47 message 48 } 49 50 /// Get a reference to the message that failed to be sent. 51 #[inline] as_inner(&self) -> &T52 pub fn as_inner(&self) -> &T { 53 unsafe { self.channel_ptr.as_ref().message().assume_init_ref() } 54 } 55 } 56 57 impl<T> Drop for SendError<T> { drop(&mut self)58 fn drop(&mut self) { 59 // SAFETY: we have ownership of the channel and require that the message is initialized 60 // upon construction 61 unsafe { 62 self.channel_ptr.as_ref().drop_message(); 63 dealloc(self.channel_ptr); 64 } 65 } 66 } 67 68 impl<T> fmt::Display for SendError<T> { fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result69 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 70 "sending on a closed channel".fmt(f) 71 } 72 } 73 74 impl<T> fmt::Debug for SendError<T> { fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result75 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 76 write!(f, "SendError<{}>(_)", stringify!(T)) 77 } 78 } 79 80 #[cfg(feature = "std")] 81 impl<T> std::error::Error for SendError<T> {} 82 83 /// An error returned from the blocking [`Receiver::recv`](crate::Receiver::recv) method. 84 /// 85 /// The receive operation can only fail if the corresponding [`Sender`](crate::Sender) was dropped 86 /// before sending any message, or if a message has already been sent and received on the channel. 87 #[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] 88 pub struct RecvError; 89 90 impl fmt::Display for RecvError { fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result91 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 92 "receiving on a closed channel".fmt(f) 93 } 94 } 95 96 #[cfg(feature = "std")] 97 impl std::error::Error for RecvError {} 98 99 /// An error returned when failing to receive a message in the non-blocking 100 /// [`Receiver::try_recv`](crate::Receiver::try_recv). 101 #[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] 102 pub enum TryRecvError { 103 /// The channel is still open, but there was no message present in it. 104 Empty, 105 106 /// The channel is closed. Either the sender was dropped before sending any message, or the 107 /// message has already been extracted from the receiver. 108 Disconnected, 109 } 110 111 impl fmt::Display for TryRecvError { fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result112 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 113 let msg = match self { 114 TryRecvError::Empty => "receiving on an empty channel", 115 TryRecvError::Disconnected => "receiving on a closed channel", 116 }; 117 msg.fmt(f) 118 } 119 } 120 121 #[cfg(feature = "std")] 122 impl std::error::Error for TryRecvError {} 123 124 /// An error returned when failing to receive a message in 125 /// [`Receiver::recv_timeout`](crate::Receiver::recv_timeout). 126 #[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] 127 pub enum RecvTimeoutError { 128 /// No message arrived on the channel before the timeout was reached. The channel is still open. 129 Timeout, 130 131 /// The channel is closed. Either the sender was dropped before sending any message, or the 132 /// message has already been extracted from the receiver. 133 Disconnected, 134 } 135 136 impl fmt::Display for RecvTimeoutError { fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result137 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 138 let msg = match self { 139 RecvTimeoutError::Timeout => "timed out waiting on channel", 140 RecvTimeoutError::Disconnected => "channel is empty and sending half is closed", 141 }; 142 msg.fmt(f) 143 } 144 } 145 146 #[cfg(feature = "std")] 147 impl std::error::Error for RecvTimeoutError {} 148