LCOV - code coverage report
Current view: top level - waltz/h2 - fd_h2_rbuf_sock.h (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 35 103 34.0 %
Date: 2025-07-01 05:00:49 Functions: 2 18 11.1 %

          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     7502457 :                             struct iovec   iov[2] ) {
      14     7502457 :   uchar * buf0 = rbuf->buf0;
      15     7502457 :   uchar * buf1 = rbuf->buf1;
      16     7502457 :   uchar * lo   = rbuf->lo;
      17     7502457 :   uchar * hi   = rbuf->hi;
      18     7502457 :   ulong free_sz = fd_h2_rbuf_free_sz( rbuf );
      19     7502457 :   if( FD_UNLIKELY( !free_sz ) ) return 0UL;
      20             : 
      21     6975015 :   if( lo<=hi ) {
      22             : 
      23     3750660 :     iov[ 0 ].iov_base = hi;
      24     3750660 :     iov[ 0 ].iov_len  = fd_ulong_min( (ulong)( buf1-hi ), free_sz );
      25     3750660 :     free_sz -= iov[ 0 ].iov_len;
      26     3750660 :     iov[ 1 ].iov_base = buf0;
      27     3750660 :     iov[ 1 ].iov_len  = fd_ulong_min( (ulong)( lo-buf0 ), free_sz );
      28     3750660 :     return 2UL;
      29             : 
      30     3750660 :   } else {
      31             : 
      32     3224355 :     iov[ 0 ].iov_base = hi;
      33     3224355 :     iov[ 0 ].iov_len  = free_sz;
      34     3224355 :     iov[ 1 ].iov_base = NULL;
      35     3224355 :     iov[ 1 ].iov_len  = 0UL;
      36     3224355 :     return 1uL;
      37             : 
      38     3224355 :   }
      39     6975015 : }
      40             : 
      41             : static inline void
      42             : fd_h2_rbuf_commit_recvmsg( fd_h2_rbuf_t *     rbuf,
      43             :                            struct iovec const iovec[2],
      44     6975015 :                            ulong              sz ) {
      45     6975015 :   uchar * buf0 = rbuf->buf0;
      46     6975015 :   uchar * buf1 = rbuf->buf1;
      47     6975015 :   struct iovec iov0 = iovec[0];
      48     6975015 :   struct iovec iov1 = iovec[1];
      49     6975015 :   rbuf->hi_off += sz;
      50     6975015 :   if( sz > iov0.iov_len ) {
      51     1773972 :     rbuf->hi = (uchar *)iov1.iov_base + ( sz - iov0.iov_len );
      52     5201043 :   } else {
      53     5201043 :     rbuf->hi = (uchar *)iov0.iov_base + sz;
      54     5201043 :   }
      55     6975015 :   if( rbuf->hi == buf1 ) rbuf->hi = buf0; /* cmov */
      56     6975015 : }
      57             : 
      58             : static inline int
      59             : fd_h2_rbuf_recvmsg( fd_h2_rbuf_t * rbuf,
      60             :                     int            sock,
      61           0 :                     int            flags ) {
      62           0 :   struct iovec iov[2];
      63           0 :   ulong iov_cnt = fd_h2_rbuf_prepare_recvmsg( rbuf, iov );
      64           0 :   if( FD_UNLIKELY( !iov_cnt ) ) return 0;
      65             : 
      66           0 :   struct msghdr msg = {
      67           0 :     .msg_iov    = iov,
      68           0 :     .msg_iovlen = iov_cnt
      69           0 :   };
      70           0 :   ssize_t sz = recvmsg( sock, &msg, flags );
      71           0 :   if( sz<0 ) {
      72           0 :     if( FD_LIKELY( errno==EAGAIN ) ) return 0;
      73           0 :     return errno;
      74           0 :   } 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           0 : }
      81             : 
      82             : static inline ulong
      83             : fd_h2_rbuf_prepare_sendmsg( fd_h2_rbuf_t * rbuf,
      84           0 :                             struct iovec   iov[2] ) {
      85           0 :   uchar * buf0 = rbuf->buf0;
      86           0 :   uchar * buf1 = rbuf->buf1;
      87           0 :   uchar * lo   = rbuf->lo;
      88           0 :   uchar * hi   = rbuf->hi;
      89           0 :   ulong used_sz = fd_h2_rbuf_used_sz( rbuf );
      90           0 :   if( FD_UNLIKELY( !used_sz ) ) return 0UL;
      91             : 
      92           0 :   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           0 :   } else {
     102             : 
     103           0 :     iov[ 0 ].iov_base = lo;
     104           0 :     iov[ 0 ].iov_len  = used_sz;
     105           0 :     iov[ 1 ].iov_base = NULL;
     106           0 :     iov[ 1 ].iov_len  = 0UL;
     107           0 :     return 1uL;
     108             : 
     109           0 :   }
     110           0 : }
     111             : 
     112             : static inline void
     113             : fd_h2_rbuf_commit_sendmsg( fd_h2_rbuf_t *     rbuf,
     114             :                            struct iovec const iovec[2],
     115           0 :                            ulong              sz ) {
     116           0 :   uchar * buf0 = rbuf->buf0;
     117           0 :   uchar * buf1 = rbuf->buf1;
     118           0 :   struct iovec iov0 = iovec[0];
     119           0 :   struct iovec iov1 = iovec[1];
     120           0 :   rbuf->lo_off += sz;
     121           0 :   if( sz > iov0.iov_len ) {
     122           0 :     rbuf->lo = (uchar *)iov1.iov_base + ( sz - iov0.iov_len );
     123           0 :   } else {
     124           0 :     rbuf->lo = (uchar *)iov0.iov_base + sz;
     125           0 :   }
     126           0 :   if( rbuf->lo == buf1 ) rbuf->lo = buf0; /* cmov */
     127           0 : }
     128             : 
     129             : static inline int
     130             : fd_h2_rbuf_sendmsg( fd_h2_rbuf_t * rbuf,
     131             :                     int            sock,
     132           0 :                     int            flags ) {
     133           0 :   struct iovec iov[2];
     134           0 :   ulong iov_cnt = fd_h2_rbuf_prepare_sendmsg( rbuf, iov );
     135           0 :   if( FD_UNLIKELY( !iov_cnt ) ) return 0;
     136             : 
     137           0 :   struct msghdr msg = {
     138           0 :     .msg_iov    = iov,
     139           0 :     .msg_iovlen = iov_cnt
     140           0 :   };
     141           0 :   ssize_t sz = sendmsg( sock, &msg, flags );
     142           0 :   if( sz<0 ) {
     143           0 :     return errno;
     144           0 :   }
     145             : 
     146           0 :   fd_h2_rbuf_commit_sendmsg( rbuf, iov, (ulong)sz );
     147           0 :   return 0;
     148           0 : }
     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