interprocess/os/unix/uds_local_socket/
stream.rs1use {
2 super::{dispatch_name, CONN_TIMEOUT_MSG},
3 crate::{
4 error::ReuniteError,
5 local_socket::{
6 prelude::*,
7 traits::{self, ReuniteResult},
8 ConcurrencyDetector, ConnectOptions, LocalSocketSite,
9 },
10 os::unix::{c_wrappers, unixprelude::*},
11 ConnectWaitMode, Sealed, TryClone,
12 },
13 std::{
14 io::{self, prelude::*, IoSlice, IoSliceMut},
15 os::unix::net::UnixStream,
16 sync::Arc,
17 time::Duration,
18 },
19};
20
21#[derive(Debug)]
23pub struct Stream(pub(super) UnixStream, ConcurrencyDetector<LocalSocketSite>);
24impl Sealed for Stream {}
25impl traits::Stream for Stream {
26 type RecvHalf = RecvHalf;
27 type SendHalf = SendHalf;
28
29 fn from_options(mut opts: &ConnectOptions<'_>) -> io::Result<Self> {
30 let nonblocking_connect = matches!(
31 opts.get_wait_mode(),
32 ConnectWaitMode::Timeout(..) | ConnectWaitMode::Deferred
33 );
34 let (stream, inprog) = dispatch_name(
35 &mut opts,
36 false,
37 |&mut opts| opts.name.borrow(),
38 |_| None,
39 |addr, _| c_wrappers::create_client(addr, nonblocking_connect),
40 )?;
41 if let ConnectWaitMode::Timeout(timeout) = opts.get_wait_mode() {
42 if inprog {
43 c_wrappers::wait_for_connect(stream.as_fd(), Some(timeout), CONN_TIMEOUT_MSG)?;
44 }
45 }
46 if opts.get_nonblocking_stream() != nonblocking_connect {
47 c_wrappers::fast_set_nonblocking(stream.as_fd(), opts.get_nonblocking_stream())?;
48 }
49 Ok(stream.into())
50 }
51
52 #[inline]
53 fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> {
54 c_wrappers::set_nonblocking(self.as_fd(), nonblocking)
55 }
56
57 #[inline]
58 fn set_recv_timeout(&self, timeout: Option<Duration>) -> io::Result<()> {
59 self.0.set_read_timeout(timeout)
60 }
61 #[inline]
62 fn set_send_timeout(&self, timeout: Option<Duration>) -> io::Result<()> {
63 self.0.set_write_timeout(timeout)
64 }
65
66 #[inline]
67 fn split(self) -> (RecvHalf, SendHalf) {
68 let arc = Arc::new(self);
69 (RecvHalf(Arc::clone(&arc)), SendHalf(arc))
70 }
71 #[inline]
72 #[allow(clippy::unwrap_in_result)]
73 fn reunite(rh: RecvHalf, sh: SendHalf) -> ReuniteResult<Self> {
74 if !Arc::ptr_eq(&rh.0, &sh.0) {
75 return Err(ReuniteError { rh, sh });
76 }
77 drop(rh);
78 let inner = Arc::into_inner(sh.0).expect("stream half inexplicably copied");
79 Ok(inner)
80 }
81}
82impl traits::StreamCommon for Stream {
83 #[inline]
84 fn take_error(&self) -> io::Result<Option<io::Error>> { c_wrappers::take_error(self.as_fd()) }
85}
86
87impl Read for &Stream {
88 fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
89 let _guard = self.1.lock();
90 (&mut &self.0).read(buf)
91 }
92 fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
93 let _guard = self.1.lock();
94 (&mut &self.0).read_vectored(bufs)
95 }
96 }
98impl Write for &Stream {
99 fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
100 let _guard = self.1.lock();
101 (&mut &self.0).write(buf)
102 }
103 fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
104 let _guard = self.1.lock();
105 (&mut &self.0).write_vectored(bufs)
106 }
107 #[inline]
108 fn flush(&mut self) -> io::Result<()> { Ok(()) }
109 }
111
112impl Stream {
114 #[inline(always)]
116 pub fn inner(&self) -> &UnixStream { &self.0 }
117 #[inline(always)]
123 pub fn inner_mut(&mut self) -> &mut UnixStream { &mut self.0 }
124}
125
126impl From<UnixStream> for Stream {
128 fn from(s: UnixStream) -> Self { Self(s, ConcurrencyDetector::new()) }
129}
130
131impl From<OwnedFd> for Stream {
132 fn from(fd: OwnedFd) -> Self { UnixStream::from(fd).into() }
133}
134
135impl TryClone for Stream {
136 #[inline]
137 fn try_clone(&self) -> std::io::Result<Self> { self.0.try_clone().map(Self::from) }
138}
139
140multimacro! {
141 Stream,
142 forward_asinto_handle(unix),
143 derive_sync_mut_rw,
144}
145
146macro_rules! arc_accessors {
147 ($ty:ty) => {
148 impl $ty {
150 #[inline]
152 pub fn as_stream(&self) -> &Stream { &self.0 }
153 #[inline]
155 pub fn into_arc(self) -> Arc<Stream> { self.0 }
156 #[inline]
159 pub fn as_arc(&self) -> &Arc<Stream> { &self.0 }
160 }
161 };
162}
163
164#[derive(Clone, Debug)]
166pub struct RecvHalf(pub(super) Arc<Stream>);
167impl Sealed for RecvHalf {}
168impl traits::RecvHalf for RecvHalf {
169 type Stream = Stream;
170
171 #[inline]
172 fn set_timeout(&self, timeout: Option<Duration>) -> io::Result<()> {
173 self.0.set_recv_timeout(timeout)
174 }
175}
176multimacro! {
177 RecvHalf,
178 forward_rbv(Stream, *),
179 arc_accessors,
180 forward_sync_ref_read,
181 forward_as_handle,
182 derive_sync_mut_read,
183}
184
185#[derive(Clone, Debug)]
187pub struct SendHalf(pub(super) Arc<Stream>);
188impl Sealed for SendHalf {}
189impl traits::SendHalf for SendHalf {
190 type Stream = Stream;
191
192 #[inline]
193 fn set_timeout(&self, timeout: Option<Duration>) -> io::Result<()> {
194 self.0.set_send_timeout(timeout)
195 }
196}
197multimacro! {
198 SendHalf,
199 forward_rbv(Stream, *),
200 arc_accessors,
201 forward_sync_ref_write,
202 forward_as_handle,
203 derive_sync_mut_write,
204}