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 */