@@ -8,15 +8,17 @@ use compio_buf::{BufResult, IntoInner, IoBuf, IoBufMut, IoVectoredBuf, IoVectore
88#[ cfg( unix) ]
99use compio_driver:: op:: CreateSocket ;
1010use compio_driver:: {
11- AsRawFd , ToSharedFd , impl_raw_fd,
11+ AsRawFd , OpCode , ToSharedFd , impl_raw_fd,
1212 op:: {
1313 Accept , BufResultExt , CloseSocket , Connect , Recv , RecvFrom , RecvFromManaged ,
1414 RecvFromVectored , RecvManaged , RecvMsg , RecvResultExt , RecvVectored , ResultTakeBuffer ,
15- Send , SendMsg , SendTo , SendToVectored , SendVectored , ShutdownSocket , VecBufResultExt ,
15+ Send , SendMsg , SendMsgZc , SendTo , SendToVectored , SendToVectoredZc , SendToZc , SendVectored ,
16+ SendVectoredZc , SendZc , ShutdownSocket , VecBufResultExt ,
1617 } ,
1718 syscall,
1819} ;
1920use compio_runtime:: { Attacher , BorrowedBuffer , BufferPool , fd:: PollFd } ;
21+ use futures_util:: StreamExt ;
2022use socket2:: { Domain , Protocol , SockAddr , Socket as Socket2 , Type } ;
2123
2224#[ derive( Debug , Clone ) ]
@@ -208,6 +210,22 @@ impl Socket {
208210 compio_runtime:: submit ( op) . await . into_inner ( )
209211 }
210212
213+ pub async fn send_zerocopy < T : IoBuf > (
214+ & self ,
215+ buf : T ,
216+ flags : i32 ,
217+ ) -> BufResult < usize , impl Future < Output = T > + use < T > > {
218+ submit_zerocopy ( SendZc :: new ( self . to_shared_fd ( ) , buf, flags) ) . await
219+ }
220+
221+ pub async fn send_zerocopy_vectored < T : IoVectoredBuf > (
222+ & self ,
223+ buf : T ,
224+ flags : i32 ,
225+ ) -> BufResult < usize , impl Future < Output = T > + use < T > > {
226+ submit_zerocopy ( SendVectoredZc :: new ( self . to_shared_fd ( ) , buf, flags) ) . await
227+ }
228+
211229 pub async fn recv_from < T : IoBufMut > (
212230 & self ,
213231 buffer : T ,
@@ -275,6 +293,26 @@ impl Socket {
275293 compio_runtime:: submit ( op) . await . into_inner ( )
276294 }
277295
296+ pub async fn send_to_zerocopy < T : IoBuf > (
297+ & self ,
298+ buffer : T ,
299+ addr : & SockAddr ,
300+ flags : i32 ,
301+ ) -> BufResult < usize , impl Future < Output = T > + use < T > > {
302+ let op = SendToZc :: new ( self . to_shared_fd ( ) , buffer, addr. clone ( ) , flags) ;
303+ submit_zerocopy ( op) . await
304+ }
305+
306+ pub async fn send_to_zerocopy_vectored < T : IoVectoredBuf > (
307+ & self ,
308+ buffer : T ,
309+ addr : & SockAddr ,
310+ flags : i32 ,
311+ ) -> BufResult < usize , impl Future < Output = T > + use < T > > {
312+ let op = SendToVectoredZc :: new ( self . to_shared_fd ( ) , buffer, addr. clone ( ) , flags) ;
313+ submit_zerocopy ( op) . await
314+ }
315+
278316 pub async fn send_msg < T : IoBuf , C : IoBuf > (
279317 & self ,
280318 buffer : T ,
@@ -299,6 +337,33 @@ impl Socket {
299337 compio_runtime:: submit ( op) . await . into_inner ( )
300338 }
301339
340+ pub async fn send_msg_zerocopy < T : IoBuf , C : IoBuf > (
341+ & self ,
342+ buffer : T ,
343+ control : C ,
344+ addr : Option < & SockAddr > ,
345+ flags : i32 ,
346+ ) -> BufResult < usize , impl Future < Output = ( T , C ) > + use < T , C > > {
347+ self . send_msg_zerocopy_vectored ( [ buffer] , control, addr, flags)
348+ . await
349+ . map_buffer ( |fut| async move {
350+ let ( [ buffer] , control) = fut. await ;
351+ ( buffer, control)
352+ } )
353+ }
354+
355+ pub async fn send_msg_zerocopy_vectored < T : IoVectoredBuf , C : IoBuf > (
356+ & self ,
357+ buffer : T ,
358+ control : C ,
359+ addr : Option < & SockAddr > ,
360+ flags : i32 ,
361+ ) -> BufResult < usize , impl Future < Output = ( T , C ) > + use < T , C > > {
362+ let fd = self . to_shared_fd ( ) ;
363+ let op = SendMsgZc :: new ( fd, buffer, control, addr. cloned ( ) , flags) ;
364+ submit_zerocopy ( op) . await
365+ }
366+
302367 #[ cfg( unix) ]
303368 pub unsafe fn get_socket_option < T : Copy > ( & self , level : i32 , name : i32 ) -> io:: Result < T > {
304369 let mut value: MaybeUninit < T > = MaybeUninit :: uninit ( ) ;
@@ -377,3 +442,27 @@ impl Socket {
377442}
378443
379444impl_raw_fd ! ( Socket , Socket2 , socket, socket) ;
445+
446+ async fn submit_zerocopy < T : OpCode + IntoInner + ' static > (
447+ op : T ,
448+ ) -> BufResult < usize , impl Future < Output = T :: Inner > + use < T > > {
449+ let mut stream = compio_runtime:: submit_multi ( op) ;
450+ let res = stream
451+ . next ( )
452+ . await
453+ . expect ( "SubmitMulti should yield at least one item" )
454+ . 0 ;
455+
456+ let fut = async move {
457+ // we don't need 2nd CQE's result
458+ _ = stream. next ( ) . await ;
459+
460+ stream
461+ . try_take ( )
462+ . map_err ( |_| ( ) )
463+ . expect ( "Cannot retrieve buffer" )
464+ . into_inner ( )
465+ } ;
466+
467+ BufResult ( res, fut)
468+ }
0 commit comments