1*bb4ee6a4SAndroid Build Coastguard Worker // Copyright 2021 The ChromiumOS Authors 2*bb4ee6a4SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be 3*bb4ee6a4SAndroid Build Coastguard Worker // found in the LICENSE file. 4*bb4ee6a4SAndroid Build Coastguard Worker 5*bb4ee6a4SAndroid Build Coastguard Worker use std::io; 6*bb4ee6a4SAndroid Build Coastguard Worker use std::time::Duration; 7*bb4ee6a4SAndroid Build Coastguard Worker 8*bb4ee6a4SAndroid Build Coastguard Worker use remain::sorted; 9*bb4ee6a4SAndroid Build Coastguard Worker use serde::de::DeserializeOwned; 10*bb4ee6a4SAndroid Build Coastguard Worker use serde::Deserialize; 11*bb4ee6a4SAndroid Build Coastguard Worker use serde::Serialize; 12*bb4ee6a4SAndroid Build Coastguard Worker use thiserror::Error as ThisError; 13*bb4ee6a4SAndroid Build Coastguard Worker 14*bb4ee6a4SAndroid Build Coastguard Worker pub use crate::sys::tube::*; 15*bb4ee6a4SAndroid Build Coastguard Worker 16*bb4ee6a4SAndroid Build Coastguard Worker impl Tube { 17*bb4ee6a4SAndroid Build Coastguard Worker /// Given a Tube end, creates two new ends, one each for sending and receiving. split_to_send_recv(self) -> Result<(SendTube, RecvTube)>18*bb4ee6a4SAndroid Build Coastguard Worker pub fn split_to_send_recv(self) -> Result<(SendTube, RecvTube)> { 19*bb4ee6a4SAndroid Build Coastguard Worker // Safe because receiving isn't allowd on this end. 20*bb4ee6a4SAndroid Build Coastguard Worker #[allow(deprecated)] 21*bb4ee6a4SAndroid Build Coastguard Worker let send_end = self.try_clone()?; 22*bb4ee6a4SAndroid Build Coastguard Worker 23*bb4ee6a4SAndroid Build Coastguard Worker Ok((SendTube(send_end), RecvTube(self))) 24*bb4ee6a4SAndroid Build Coastguard Worker } 25*bb4ee6a4SAndroid Build Coastguard Worker 26*bb4ee6a4SAndroid Build Coastguard Worker /// Creates a Send/Recv pair of Tubes. directional_pair() -> Result<(SendTube, RecvTube)>27*bb4ee6a4SAndroid Build Coastguard Worker pub fn directional_pair() -> Result<(SendTube, RecvTube)> { 28*bb4ee6a4SAndroid Build Coastguard Worker let (t1, t2) = Self::pair()?; 29*bb4ee6a4SAndroid Build Coastguard Worker Ok((SendTube(t1), RecvTube(t2))) 30*bb4ee6a4SAndroid Build Coastguard Worker } 31*bb4ee6a4SAndroid Build Coastguard Worker try_clone_send_tube(&self) -> Result<SendTube>32*bb4ee6a4SAndroid Build Coastguard Worker pub fn try_clone_send_tube(&self) -> Result<SendTube> { 33*bb4ee6a4SAndroid Build Coastguard Worker // Safe because receiving is only allowed on original Tube. 34*bb4ee6a4SAndroid Build Coastguard Worker #[allow(deprecated)] 35*bb4ee6a4SAndroid Build Coastguard Worker let send_end = self.try_clone()?; 36*bb4ee6a4SAndroid Build Coastguard Worker Ok(SendTube(send_end)) 37*bb4ee6a4SAndroid Build Coastguard Worker } 38*bb4ee6a4SAndroid Build Coastguard Worker } 39*bb4ee6a4SAndroid Build Coastguard Worker 40*bb4ee6a4SAndroid Build Coastguard Worker use crate::AsRawDescriptor; 41*bb4ee6a4SAndroid Build Coastguard Worker use crate::ReadNotifier; 42*bb4ee6a4SAndroid Build Coastguard Worker 43*bb4ee6a4SAndroid Build Coastguard Worker #[derive(Serialize, Deserialize)] 44*bb4ee6a4SAndroid Build Coastguard Worker #[serde(transparent)] 45*bb4ee6a4SAndroid Build Coastguard Worker /// A Tube end which can only send messages. Cloneable. 46*bb4ee6a4SAndroid Build Coastguard Worker pub struct SendTube(pub(crate) Tube); 47*bb4ee6a4SAndroid Build Coastguard Worker 48*bb4ee6a4SAndroid Build Coastguard Worker #[allow(dead_code)] 49*bb4ee6a4SAndroid Build Coastguard Worker impl SendTube { 50*bb4ee6a4SAndroid Build Coastguard Worker /// TODO(b/145998747, b/184398671): this method should be removed. set_send_timeout(&self, _timeout: Option<Duration>) -> Result<()>51*bb4ee6a4SAndroid Build Coastguard Worker pub fn set_send_timeout(&self, _timeout: Option<Duration>) -> Result<()> { 52*bb4ee6a4SAndroid Build Coastguard Worker unimplemented!("To be removed/refactored upstream."); 53*bb4ee6a4SAndroid Build Coastguard Worker } 54*bb4ee6a4SAndroid Build Coastguard Worker send<T: Serialize>(&self, msg: &T) -> Result<()>55*bb4ee6a4SAndroid Build Coastguard Worker pub fn send<T: Serialize>(&self, msg: &T) -> Result<()> { 56*bb4ee6a4SAndroid Build Coastguard Worker self.0.send(msg) 57*bb4ee6a4SAndroid Build Coastguard Worker } 58*bb4ee6a4SAndroid Build Coastguard Worker try_clone(&self) -> Result<Self>59*bb4ee6a4SAndroid Build Coastguard Worker pub fn try_clone(&self) -> Result<Self> { 60*bb4ee6a4SAndroid Build Coastguard Worker Ok(SendTube( 61*bb4ee6a4SAndroid Build Coastguard Worker #[allow(deprecated)] 62*bb4ee6a4SAndroid Build Coastguard Worker self.0.try_clone()?, 63*bb4ee6a4SAndroid Build Coastguard Worker )) 64*bb4ee6a4SAndroid Build Coastguard Worker } 65*bb4ee6a4SAndroid Build Coastguard Worker 66*bb4ee6a4SAndroid Build Coastguard Worker /// Never call this function, it is for use by cros_async to provide 67*bb4ee6a4SAndroid Build Coastguard Worker /// directional wrapper types only. Using it in any other context may 68*bb4ee6a4SAndroid Build Coastguard Worker /// violate concurrency assumptions. (Type splitting across crates has put 69*bb4ee6a4SAndroid Build Coastguard Worker /// us in a situation where we can't use Rust privacy to enforce this.) 70*bb4ee6a4SAndroid Build Coastguard Worker #[deprecated] into_tube(self) -> Tube71*bb4ee6a4SAndroid Build Coastguard Worker pub fn into_tube(self) -> Tube { 72*bb4ee6a4SAndroid Build Coastguard Worker self.0 73*bb4ee6a4SAndroid Build Coastguard Worker } 74*bb4ee6a4SAndroid Build Coastguard Worker } 75*bb4ee6a4SAndroid Build Coastguard Worker 76*bb4ee6a4SAndroid Build Coastguard Worker #[derive(Serialize, Deserialize)] 77*bb4ee6a4SAndroid Build Coastguard Worker #[serde(transparent)] 78*bb4ee6a4SAndroid Build Coastguard Worker /// A Tube end which can only recv messages. 79*bb4ee6a4SAndroid Build Coastguard Worker pub struct RecvTube(pub(crate) Tube); 80*bb4ee6a4SAndroid Build Coastguard Worker 81*bb4ee6a4SAndroid Build Coastguard Worker #[allow(dead_code)] 82*bb4ee6a4SAndroid Build Coastguard Worker impl RecvTube { recv<T: DeserializeOwned>(&self) -> Result<T>83*bb4ee6a4SAndroid Build Coastguard Worker pub fn recv<T: DeserializeOwned>(&self) -> Result<T> { 84*bb4ee6a4SAndroid Build Coastguard Worker self.0.recv() 85*bb4ee6a4SAndroid Build Coastguard Worker } 86*bb4ee6a4SAndroid Build Coastguard Worker 87*bb4ee6a4SAndroid Build Coastguard Worker /// TODO(b/145998747, b/184398671): this method should be removed. set_recv_timeout(&self, _timeout: Option<Duration>) -> Result<()>88*bb4ee6a4SAndroid Build Coastguard Worker pub fn set_recv_timeout(&self, _timeout: Option<Duration>) -> Result<()> { 89*bb4ee6a4SAndroid Build Coastguard Worker unimplemented!("To be removed/refactored upstream."); 90*bb4ee6a4SAndroid Build Coastguard Worker } 91*bb4ee6a4SAndroid Build Coastguard Worker 92*bb4ee6a4SAndroid Build Coastguard Worker /// Never call this function, it is for use by cros_async to provide 93*bb4ee6a4SAndroid Build Coastguard Worker /// directional wrapper types only. Using it in any other context may 94*bb4ee6a4SAndroid Build Coastguard Worker /// violate concurrency assumptions. (Type splitting across crates has put 95*bb4ee6a4SAndroid Build Coastguard Worker /// us in a situation where we can't use Rust privacy to enforce this.) 96*bb4ee6a4SAndroid Build Coastguard Worker #[deprecated] into_tube(self) -> Tube97*bb4ee6a4SAndroid Build Coastguard Worker pub fn into_tube(self) -> Tube { 98*bb4ee6a4SAndroid Build Coastguard Worker self.0 99*bb4ee6a4SAndroid Build Coastguard Worker } 100*bb4ee6a4SAndroid Build Coastguard Worker } 101*bb4ee6a4SAndroid Build Coastguard Worker 102*bb4ee6a4SAndroid Build Coastguard Worker impl ReadNotifier for RecvTube { get_read_notifier(&self) -> &dyn AsRawDescriptor103*bb4ee6a4SAndroid Build Coastguard Worker fn get_read_notifier(&self) -> &dyn AsRawDescriptor { 104*bb4ee6a4SAndroid Build Coastguard Worker self.0.get_read_notifier() 105*bb4ee6a4SAndroid Build Coastguard Worker } 106*bb4ee6a4SAndroid Build Coastguard Worker } 107*bb4ee6a4SAndroid Build Coastguard Worker 108*bb4ee6a4SAndroid Build Coastguard Worker #[sorted] 109*bb4ee6a4SAndroid Build Coastguard Worker #[derive(ThisError, Debug)] 110*bb4ee6a4SAndroid Build Coastguard Worker pub enum Error { 111*bb4ee6a4SAndroid Build Coastguard Worker #[cfg(windows)] 112*bb4ee6a4SAndroid Build Coastguard Worker #[error("attempt to duplicate descriptor via broker failed")] 113*bb4ee6a4SAndroid Build Coastguard Worker BrokerDupDescriptor, 114*bb4ee6a4SAndroid Build Coastguard Worker #[error("failed to clone transport: {0}")] 115*bb4ee6a4SAndroid Build Coastguard Worker Clone(io::Error), 116*bb4ee6a4SAndroid Build Coastguard Worker #[error("tube was disconnected")] 117*bb4ee6a4SAndroid Build Coastguard Worker Disconnected, 118*bb4ee6a4SAndroid Build Coastguard Worker #[error("failed to duplicate descriptor: {0}")] 119*bb4ee6a4SAndroid Build Coastguard Worker DupDescriptor(io::Error), 120*bb4ee6a4SAndroid Build Coastguard Worker #[cfg(windows)] 121*bb4ee6a4SAndroid Build Coastguard Worker #[error("failed to flush named pipe: {0}")] 122*bb4ee6a4SAndroid Build Coastguard Worker Flush(io::Error), 123*bb4ee6a4SAndroid Build Coastguard Worker #[cfg(unix)] 124*bb4ee6a4SAndroid Build Coastguard Worker #[error("byte framing mode is not supported")] 125*bb4ee6a4SAndroid Build Coastguard Worker InvalidFramingMode, 126*bb4ee6a4SAndroid Build Coastguard Worker #[error("failed to serialize/deserialize json from packet: {0}")] 127*bb4ee6a4SAndroid Build Coastguard Worker Json(serde_json::Error), 128*bb4ee6a4SAndroid Build Coastguard Worker #[error("cancelled a queued async operation")] 129*bb4ee6a4SAndroid Build Coastguard Worker OperationCancelled, 130*bb4ee6a4SAndroid Build Coastguard Worker #[error("failed to crate tube pair: {0}")] 131*bb4ee6a4SAndroid Build Coastguard Worker Pair(io::Error), 132*bb4ee6a4SAndroid Build Coastguard Worker #[cfg(any(windows, feature = "proto_tube"))] 133*bb4ee6a4SAndroid Build Coastguard Worker #[error("encountered protobuf error: {0}")] 134*bb4ee6a4SAndroid Build Coastguard Worker Proto(protobuf::Error), 135*bb4ee6a4SAndroid Build Coastguard Worker #[error("failed to receive packet: {0}")] 136*bb4ee6a4SAndroid Build Coastguard Worker Recv(io::Error), 137*bb4ee6a4SAndroid Build Coastguard Worker #[error("attempted to receive too many file descriptors")] 138*bb4ee6a4SAndroid Build Coastguard Worker RecvTooManyFds, 139*bb4ee6a4SAndroid Build Coastguard Worker #[error("Received a message with a zero sized body. This should not happen.")] 140*bb4ee6a4SAndroid Build Coastguard Worker RecvUnexpectedEmptyBody, 141*bb4ee6a4SAndroid Build Coastguard Worker #[error("failed to send packet: {0}")] 142*bb4ee6a4SAndroid Build Coastguard Worker Send(io::Error), 143*bb4ee6a4SAndroid Build Coastguard Worker #[error("failed to write packet to intermediate buffer: {0}")] 144*bb4ee6a4SAndroid Build Coastguard Worker SendIoBuf(io::Error), 145*bb4ee6a4SAndroid Build Coastguard Worker #[error("attempted to send too many file descriptors")] 146*bb4ee6a4SAndroid Build Coastguard Worker SendTooManyFds, 147*bb4ee6a4SAndroid Build Coastguard Worker #[error("failed to set recv timeout: {0}")] 148*bb4ee6a4SAndroid Build Coastguard Worker SetRecvTimeout(io::Error), 149*bb4ee6a4SAndroid Build Coastguard Worker #[error("failed to set send timeout: {0}")] 150*bb4ee6a4SAndroid Build Coastguard Worker SetSendTimeout(io::Error), 151*bb4ee6a4SAndroid Build Coastguard Worker } 152*bb4ee6a4SAndroid Build Coastguard Worker 153*bb4ee6a4SAndroid Build Coastguard Worker pub type Result<T> = std::result::Result<T, Error>; 154