Skip to main content

compio_io\ancillary/
io.rs

1#[cfg(feature = "allocator_api")]
2use std::alloc::Allocator;
3
4use compio_buf::{BufResult, IoBuf, IoBufMut, IoVectoredBuf, IoVectoredBufMut, t_alloc};
5use futures_util::Stream;
6use rustix::net::ReturnFlags;
7
8use crate::{AsyncReadManaged, IoResult};
9
10/// Trait for asynchronous read with ancillary (control) data.
11/// Intended for connected stream sockets (TCP, Unix streams) where no source
12/// address is needed.
13pub trait AsyncReadAncillary {
14    /// Read data with ancillary data into an owned buffer, returning bytes
15    /// read, control length, and `recvmsg` flags.
16    async fn read_with_ancillary<T: IoBufMut, C: IoBufMut>(
17        &mut self,
18        buffer: T,
19        control: C,
20    ) -> BufResult<(usize, usize, ReturnFlags), (T, C)>;
21
22    /// Read data with ancillary data into a vectored buffer, returning bytes
23    /// read, control length, and `recvmsg` flags.
24    async fn read_vectored_with_ancillary<T: IoVectoredBufMut, C: IoBufMut>(
25        &mut self,
26        buffer: T,
27        control: C,
28    ) -> BufResult<(usize, usize, ReturnFlags), (T, C)>;
29}
30
31impl<A: AsyncReadAncillary + ?Sized> AsyncReadAncillary for &mut A {
32    #[inline]
33    async fn read_with_ancillary<T: IoBufMut, C: IoBufMut>(
34        &mut self,
35        buffer: T,
36        control: C,
37    ) -> BufResult<(usize, usize, ReturnFlags), (T, C)> {
38        (**self).read_with_ancillary(buffer, control).await
39    }
40
41    #[inline]
42    async fn read_vectored_with_ancillary<T: IoVectoredBufMut, C: IoBufMut>(
43        &mut self,
44        buffer: T,
45        control: C,
46    ) -> BufResult<(usize, usize, ReturnFlags), (T, C)> {
47        (**self).read_vectored_with_ancillary(buffer, control).await
48    }
49}
50
51impl<A: AsyncReadAncillary + ?Sized, #[cfg(feature = "allocator_api")] Alloc: Allocator>
52    AsyncReadAncillary for t_alloc!(Box, A, Alloc)
53{
54    #[inline]
55    async fn read_with_ancillary<T: IoBufMut, C: IoBufMut>(
56        &mut self,
57        buffer: T,
58        control: C,
59    ) -> BufResult<(usize, usize, ReturnFlags), (T, C)> {
60        (**self).read_with_ancillary(buffer, control).await
61    }
62
63    #[inline]
64    async fn read_vectored_with_ancillary<T: IoVectoredBufMut, C: IoBufMut>(
65        &mut self,
66        buffer: T,
67        control: C,
68    ) -> BufResult<(usize, usize, ReturnFlags), (T, C)> {
69        (**self).read_vectored_with_ancillary(buffer, control).await
70    }
71}
72
73/// Trait for asynchronous write with ancillary (control) data.
74/// Intended for connected stream sockets (TCP, Unix streams) where no
75/// destination address is needed.
76pub trait AsyncWriteAncillary {
77    /// Write data with ancillary data from an owned buffer.
78    async fn write_with_ancillary<T: IoBuf, C: IoBuf>(
79        &mut self,
80        buffer: T,
81        control: C,
82    ) -> BufResult<usize, (T, C)>;
83
84    /// Write data with ancillary data from a vectored buffer.
85    async fn write_vectored_with_ancillary<T: IoVectoredBuf, C: IoBuf>(
86        &mut self,
87        buffer: T,
88        control: C,
89    ) -> BufResult<usize, (T, C)>;
90}
91
92impl<A: AsyncWriteAncillary + ?Sized> AsyncWriteAncillary for &mut A {
93    #[inline]
94    async fn write_with_ancillary<T: IoBuf, C: IoBuf>(
95        &mut self,
96        buffer: T,
97        control: C,
98    ) -> BufResult<usize, (T, C)> {
99        (**self).write_with_ancillary(buffer, control).await
100    }
101
102    #[inline]
103    async fn write_vectored_with_ancillary<T: IoVectoredBuf, C: IoBuf>(
104        &mut self,
105        buffer: T,
106        control: C,
107    ) -> BufResult<usize, (T, C)> {
108        (**self)
109            .write_vectored_with_ancillary(buffer, control)
110            .await
111    }
112}
113
114impl<A: AsyncWriteAncillary + ?Sized, #[cfg(feature = "allocator_api")] Alloc: Allocator>
115    AsyncWriteAncillary for t_alloc!(Box, A, Alloc)
116{
117    #[inline]
118    async fn write_with_ancillary<T: IoBuf, C: IoBuf>(
119        &mut self,
120        buffer: T,
121        control: C,
122    ) -> BufResult<usize, (T, C)> {
123        (**self).write_with_ancillary(buffer, control).await
124    }
125
126    #[inline]
127    async fn write_vectored_with_ancillary<T: IoVectoredBuf, C: IoBuf>(
128        &mut self,
129        buffer: T,
130        control: C,
131    ) -> BufResult<usize, (T, C)> {
132        (**self)
133            .write_vectored_with_ancillary(buffer, control)
134            .await
135    }
136}
137
138/// Trait for zerocopy asynchronous write with ancillary (control) data.
139/// Intended for connected stream sockets (TCP, Unix streams) where no
140/// destination address is needed.
141pub trait AsyncWriteAncillaryZerocopy {
142    /// The future that will be resolved when the buffer is safe to be reused.
143    type BufferReadyFuture<T: IoBuf, C: IoBuf>: Future<Output = (T, C)>;
144    /// The future that will be resolved when the vectored buffer is safe to be
145    /// reused.
146    type VectoredBufferReadyFuture<T: IoVectoredBuf, C: IoBuf>: Future<Output = (T, C)>;
147
148    /// Write some bytes from buffer into this source using the underlying
149    /// zero-copy mechanism. It returns a result of the underlying write
150    /// operation and a future that will be resolved when the buffer is safe
151    /// to be reused.
152    fn write_zerocopy_with_ancillary<T: IoBuf, C: IoBuf>(
153        &mut self,
154        buf: T,
155        control: C,
156    ) -> impl Future<Output = BufResult<usize, Self::BufferReadyFuture<T, C>>>;
157
158    /// Like `write_zerocopy_with_ancillary`, except that it writes from a
159    /// buffer implements [`IoVectoredBuf`] into the source.
160    fn write_zerocopy_vectored_with_ancillary<T: IoVectoredBuf, C: IoBuf>(
161        &mut self,
162        buf: T,
163        control: C,
164    ) -> impl Future<Output = BufResult<usize, Self::VectoredBufferReadyFuture<T, C>>>;
165}
166
167impl<A: AsyncWriteAncillaryZerocopy + ?Sized> AsyncWriteAncillaryZerocopy for &mut A {
168    type BufferReadyFuture<T: IoBuf, C: IoBuf> = A::BufferReadyFuture<T, C>;
169    type VectoredBufferReadyFuture<T: IoVectoredBuf, C: IoBuf> = A::VectoredBufferReadyFuture<T, C>;
170
171    #[inline]
172    fn write_zerocopy_with_ancillary<T: IoBuf, C: IoBuf>(
173        &mut self,
174        buf: T,
175        control: C,
176    ) -> impl Future<Output = BufResult<usize, Self::BufferReadyFuture<T, C>>> {
177        (**self).write_zerocopy_with_ancillary(buf, control)
178    }
179
180    #[inline]
181    fn write_zerocopy_vectored_with_ancillary<T: IoVectoredBuf, C: IoBuf>(
182        &mut self,
183        buf: T,
184        control: C,
185    ) -> impl Future<Output = BufResult<usize, Self::VectoredBufferReadyFuture<T, C>>> {
186        (**self).write_zerocopy_vectored_with_ancillary(buf, control)
187    }
188}
189
190impl<A: AsyncWriteAncillaryZerocopy + ?Sized, #[cfg(feature = "allocator_api")] Alloc: Allocator>
191    AsyncWriteAncillaryZerocopy for t_alloc!(Box, A, Alloc)
192{
193    type BufferReadyFuture<T: IoBuf, C: IoBuf> = A::BufferReadyFuture<T, C>;
194    type VectoredBufferReadyFuture<T: IoVectoredBuf, C: IoBuf> = A::VectoredBufferReadyFuture<T, C>;
195
196    fn write_zerocopy_with_ancillary<T: IoBuf, C: IoBuf>(
197        &mut self,
198        buf: T,
199        control: C,
200    ) -> impl Future<Output = BufResult<usize, Self::BufferReadyFuture<T, C>>> {
201        (**self).write_zerocopy_with_ancillary(buf, control)
202    }
203
204    fn write_zerocopy_vectored_with_ancillary<T: IoVectoredBuf, C: IoBuf>(
205        &mut self,
206        buf: T,
207        control: C,
208    ) -> impl Future<Output = BufResult<usize, Self::VectoredBufferReadyFuture<T, C>>> {
209        (**self).write_zerocopy_vectored_with_ancillary(buf, control)
210    }
211}
212
213/// Trait for asynchronous read with ancillary (control) data that returns
214/// managed buffers. Intended for connected stream sockets (TCP, Unix streams)
215/// where no source address is needed.
216pub trait AsyncReadAncillaryManaged: AsyncReadManaged {
217    /// Read data into a managed buffer with ancillary data.
218    ///
219    /// # Implementation Note
220    ///
221    /// - If `len` == 0, implementation should use buffer's size as `len`
222    /// - if `len` > 0, `min(len, buffer_size)` will be the max number of bytes
223    ///   to be read.
224    async fn read_managed_with_ancillary<C: IoBufMut>(
225        &mut self,
226        len: usize,
227        control: C,
228    ) -> IoResult<Option<(Self::Buffer, C, ReturnFlags)>>;
229}
230
231/// Trait for asynchronous read with ancillary (control) data that returns
232/// multiple managed buffers. Intended for connected stream sockets (TCP, Unix
233/// streams) where no source address is needed.
234pub trait AsyncReadAncillaryMulti {
235    /// A wrapped type for the payload data and the ancillary data.
236    type Return;
237
238    /// Read data and ancillary data into multiple managed buffers.
239    fn read_multi_with_ancillary(
240        &mut self,
241        control_len: usize,
242    ) -> impl Stream<Item = IoResult<Self::Return>>;
243}