blob: 56a8479b07c7a53767af8db04226546d052db93f [file] [log] [blame]
// Copyright 2021 The ChromiumOS Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
use std::io;
use std::time::Duration;
use remain::sorted;
use serde::de::DeserializeOwned;
use serde::Deserialize;
use serde::Serialize;
use thiserror::Error as ThisError;
pub use crate::sys::tube::*;
impl Tube {
/// Given a Tube end, creates two new ends, one each for sending and receiving.
pub fn split_to_send_recv(self) -> Result<(SendTube, RecvTube)> {
// Safe because receiving isn't allowd on this end.
#[allow(deprecated)]
let send_end = self.try_clone()?;
Ok((SendTube(send_end), RecvTube(self)))
}
/// Creates a Send/Recv pair of Tubes.
pub fn directional_pair() -> Result<(SendTube, RecvTube)> {
let (t1, t2) = Self::pair()?;
Ok((SendTube(t1), RecvTube(t2)))
}
pub fn try_clone_send_tube(&self) -> Result<SendTube> {
// Safe because receiving is only allowed on original Tube.
#[allow(deprecated)]
let send_end = self.try_clone()?;
Ok(SendTube(send_end))
}
}
use crate::AsRawDescriptor;
use crate::ReadNotifier;
#[derive(Serialize, Deserialize)]
#[serde(transparent)]
/// A Tube end which can only send messages. Cloneable.
pub struct SendTube(pub(crate) Tube);
#[allow(dead_code)]
impl SendTube {
/// TODO(b/145998747, b/184398671): this method should be removed.
pub fn set_send_timeout(&self, _timeout: Option<Duration>) -> Result<()> {
unimplemented!("To be removed/refactored upstream.");
}
pub fn send<T: Serialize>(&self, msg: &T) -> Result<()> {
self.0.send(msg)
}
pub fn try_clone(&self) -> Result<Self> {
Ok(SendTube(
#[allow(deprecated)]
self.0.try_clone()?,
))
}
/// Never call this function, it is for use by cros_async to provide
/// directional wrapper types only. Using it in any other context may
/// violate concurrency assumptions. (Type splitting across crates has put
/// us in a situation where we can't use Rust privacy to enforce this.)
#[deprecated]
pub fn into_tube(self) -> Tube {
self.0
}
}
#[derive(Serialize, Deserialize)]
#[serde(transparent)]
/// A Tube end which can only recv messages.
pub struct RecvTube(pub(crate) Tube);
#[allow(dead_code)]
impl RecvTube {
pub fn recv<T: DeserializeOwned>(&self) -> Result<T> {
self.0.recv()
}
/// TODO(b/145998747, b/184398671): this method should be removed.
pub fn set_recv_timeout(&self, _timeout: Option<Duration>) -> Result<()> {
unimplemented!("To be removed/refactored upstream.");
}
/// Never call this function, it is for use by cros_async to provide
/// directional wrapper types only. Using it in any other context may
/// violate concurrency assumptions. (Type splitting across crates has put
/// us in a situation where we can't use Rust privacy to enforce this.)
#[deprecated]
pub fn into_tube(self) -> Tube {
self.0
}
}
impl ReadNotifier for RecvTube {
fn get_read_notifier(&self) -> &dyn AsRawDescriptor {
self.0.get_read_notifier()
}
}
#[sorted]
#[derive(ThisError, Debug)]
pub enum Error {
#[cfg(windows)]
#[error("attempt to duplicate descriptor via broker failed")]
BrokerDupDescriptor,
#[error("failed to clone transport: {0}")]
Clone(io::Error),
#[error("tube was disconnected")]
Disconnected,
#[error("failed to duplicate descriptor: {0}")]
DupDescriptor(io::Error),
#[cfg(windows)]
#[error("failed to flush named pipe: {0}")]
Flush(io::Error),
#[cfg(any(target_os = "android", target_os = "linux"))]
#[error("byte framing mode is not supported")]
InvalidFramingMode,
#[error("failed to serialize/deserialize json from packet: {0}")]
Json(serde_json::Error),
#[error("cancelled a queued async operation")]
OperationCancelled,
#[error("failed to crate tube pair: {0}")]
Pair(io::Error),
#[cfg(any(windows, feature = "proto_tube"))]
#[error("encountered protobuf error: {0}")]
Proto(protobuf::Error),
#[error("failed to receive packet: {0}")]
Recv(io::Error),
#[error("Received a message with a zero sized body. This should not happen.")]
RecvUnexpectedEmptyBody,
#[error("failed to send packet: {0}")]
Send(io::Error),
#[error("failed to write packet to intermediate buffer: {0}")]
SendIoBuf(io::Error),
#[error("attempted to send too many file descriptors")]
SendTooManyFds,
#[error("failed to set recv timeout: {0}")]
SetRecvTimeout(io::Error),
#[error("failed to set send timeout: {0}")]
SetSendTimeout(io::Error),
}
pub type Result<T> = std::result::Result<T, Error>;