LCOV - code coverage report
Current view: top level - waltz/h2 - fd_h2_rbuf_sock.h (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 70 103 68.0 %
Date: 2026-09-17 04:28:31 Functions: 5 18 27.8 %

          Line data    Source code
       1             : #ifndef HEADER_fd_src_waltz_h2_fd_h2_rbuf_sock_h
       2             : #define HEADER_fd_src_waltz_h2_fd_h2_rbuf_sock_h
       3             : 
       4             : #include "fd_h2_rbuf.h"
       5             : 
       6             : #if FD_H2_HAS_SOCKETS
       7             : 
       8             : #include <errno.h>
       9             : #include <sys/socket.h>
      10             : 
      11             : static inline ulong
      12             : fd_h2_rbuf_prepare_recvmsg( fd_h2_rbuf_t * rbuf,
      13          27 :                             struct iovec   iov[2] ) {
      14          27 :   uchar * buf0 = rbuf->buf0;
      15          27 :   uchar * buf1 = rbuf->buf1;
      16          27 :   uchar * lo   = rbuf->lo;
      17          27 :   uchar * hi   = rbuf->hi;
      18          27 :   ulong free_sz = fd_h2_rbuf_free_sz( rbuf );
      19          27 :   if( FD_UNLIKELY( !free_sz ) ) return 0UL;
      20             : 
      21          27 :   if( lo<=hi ) {
      22             : 
      23          27 :     iov[ 0 ].iov_base = hi;
      24          27 :     iov[ 0 ].iov_len  = fd_ulong_min( (ulong)( buf1-hi ), free_sz );
      25          27 :     free_sz -= iov[ 0 ].iov_len;
      26          27 :     iov[ 1 ].iov_base = buf0;
      27          27 :     iov[ 1 ].iov_len  = fd_ulong_min( (ulong)( lo-buf0 ), free_sz );
      28          27 :     return 2UL;
      29             : 
      30          27 :   } else {
      31             : 
      32           0 :     iov[ 0 ].iov_base = hi;
      33           0 :     iov[ 0 ].iov_len  = free_sz;
      34           0 :     iov[ 1 ].iov_base = NULL;
      35           0 :     iov[ 1 ].iov_len  = 0UL;
      36           0 :     return 1uL;
      37             : 
      38           0 :   }
      39          27 : }
      40             : 
      41             : static inline void
      42             : fd_h2_rbuf_commit_recvmsg( fd_h2_rbuf_t *     rbuf,
      43             :                            struct iovec const iovec[2],
      44           0 :                            ulong              sz ) {
      45           0 :   uchar * buf0 = rbuf->buf0;
      46           0 :   uchar * buf1 = rbuf->buf1;
      47           0 :   struct iovec iov0 = iovec[0];
      48           0 :   struct iovec iov1 = iovec[1];
      49           0 :   rbuf->hi_off += sz;
      50           0 :   if( sz > iov0.iov_len ) {
      51           0 :     rbuf->hi = (uchar *)iov1.iov_base + ( sz - iov0.iov_len );
      52           0 :   } else {
      53           0 :     rbuf->hi = (uchar *)iov0.iov_base + sz;
      54           0 :   }
      55           0 :   if( rbuf->hi == buf1 ) rbuf->hi = buf0; /* cmov */
      56           0 : }
      57             : 
      58             : static inline int
      59             : fd_h2_rbuf_recvmsg( fd_h2_rbuf_t * rbuf,
      60             :                     int            sock,
      61          27 :                     int            flags ) {
      62          27 :   struct iovec iov[2];
      63          27 :   ulong iov_cnt = fd_h2_rbuf_prepare_recvmsg( rbuf, iov );
      64          27 :   if( FD_UNLIKELY( !iov_cnt ) ) return 0;
      65             : 
      66          27 :   struct msghdr msg = {
      67          27 :     .msg_iov    = iov,
      68          27 :     .msg_iovlen = iov_cnt
      69          27 :   };
      70          27 :   ssize_t sz = recvmsg( sock, &msg, flags );
      71          27 :   if( sz<0 ) {
      72          27 :     if( FD_LIKELY( errno==EAGAIN ) ) return 0;
      73           0 :     return errno;
      74          27 :   } else if( FD_UNLIKELY( sz==0 ) ) {
      75           0 :     return EPIPE;
      76           0 :   }
      77             : 
      78           0 :   fd_h2_rbuf_commit_recvmsg( rbuf, iov, (ulong)sz );
      79           0 :   return 0;
      80          27 : }
      81             : 
      82             : static inline ulong
      83             : fd_h2_rbuf_prepare_sendmsg( fd_h2_rbuf_t * rbuf,
      84          39 :                             struct iovec   iov[2] ) {
      85          39 :   uchar * buf0 = rbuf->buf0;
      86          39 :   uchar * buf1 = rbuf->buf1;
      87          39 :   uchar * lo   = rbuf->lo;
      88          39 :   uchar * hi   = rbuf->hi;
      89          39 :   ulong used_sz = fd_h2_rbuf_used_sz( rbuf );
      90          39 :   if( FD_UNLIKELY( !used_sz ) ) return 0UL;
      91             : 
      92          12 :   if( hi<=lo ) {
      93             : 
      94           0 :     iov[ 0 ].iov_base = lo;
      95           0 :     iov[ 0 ].iov_len  = fd_ulong_min( (ulong)( buf1-lo ), used_sz );
      96           0 :     used_sz -= iov[ 0 ].iov_len;
      97           0 :     iov[ 1 ].iov_base = buf0;
      98           0 :     iov[ 1 ].iov_len  = fd_ulong_min( (ulong)( hi-buf0 ), used_sz );
      99           0 :     return 2UL;
     100             : 
     101          12 :   } else {
     102             : 
     103          12 :     iov[ 0 ].iov_base = lo;
     104          12 :     iov[ 0 ].iov_len  = used_sz;
     105          12 :     iov[ 1 ].iov_base = NULL;
     106          12 :     iov[ 1 ].iov_len  = 0UL;
     107          12 :     return 1uL;
     108             : 
     109          12 :   }
     110          12 : }
     111             : 
     112             : static inline void
     113             : fd_h2_rbuf_commit_sendmsg( fd_h2_rbuf_t *     rbuf,
     114             :                            struct iovec const iovec[2],
     115          12 :                            ulong              sz ) {
     116          12 :   uchar * buf0 = rbuf->buf0;
     117          12 :   uchar * buf1 = rbuf->buf1;
     118          12 :   struct iovec iov0 = iovec[0];
     119          12 :   struct iovec iov1 = iovec[1];
     120          12 :   rbuf->lo_off += sz;
     121          12 :   if( sz > iov0.iov_len ) {
     122           0 :     rbuf->lo = (uchar *)iov1.iov_base + ( sz - iov0.iov_len );
     123          12 :   } else {
     124          12 :     rbuf->lo = (uchar *)iov0.iov_base + sz;
     125          12 :   }
     126          12 :   if( rbuf->lo == buf1 ) rbuf->lo = buf0; /* cmov */
     127          12 : }
     128             : 
     129             : static inline int
     130             : fd_h2_rbuf_sendmsg( fd_h2_rbuf_t * rbuf,
     131             :                     int            sock,
     132          39 :                     int            flags ) {
     133          39 :   struct iovec iov[2];
     134          39 :   ulong iov_cnt = fd_h2_rbuf_prepare_sendmsg( rbuf, iov );
     135          39 :   if( FD_UNLIKELY( !iov_cnt ) ) return 0;
     136             : 
     137          12 :   struct msghdr msg = {
     138          12 :     .msg_iov    = iov,
     139          12 :     .msg_iovlen = iov_cnt
     140          12 :   };
     141          12 :   ssize_t sz = sendmsg( sock, &msg, flags );
     142          12 :   if( sz<0 ) {
     143           0 :     return errno;
     144           0 :   }
     145             : 
     146          12 :   fd_h2_rbuf_commit_sendmsg( rbuf, iov, (ulong)sz );
     147          12 :   return 0;
     148          12 : }
     149             : 
     150             : #endif /* FD_H2_HAS_SOCKETS */
     151             : 
     152             : #endif /* HEADER_fd_src_waltz_h2_fd_h2_rbuf_sock_h */

Generated by: LCOV version 1.14