Coverage Report

Created: 2025-12-31 06:16

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