Line data Source code
1 : #include "fd_h2_tx.h" 2 : #include "fd_h2_conn.h" 3 : #include "fd_h2_stream.h" 4 : 5 : void 6 : fd_h2_tx_op_copy( fd_h2_conn_t * conn, 7 : fd_h2_stream_t * stream, 8 : fd_h2_rbuf_t * rbuf_tx, 9 9 : fd_h2_tx_op_t * tx_op ) { 10 9 : long quota = fd_long_min( conn->tx_wnd, stream->tx_wnd ); 11 9 : if( FD_UNLIKELY( quota<0L ) ) return; 12 : 13 9 : if( FD_UNLIKELY( stream->state == FD_H2_STREAM_STATE_CLOSED ) ) return; 14 9 : if( FD_UNLIKELY( stream->state != FD_H2_STREAM_STATE_OPEN && 15 9 : stream->state != FD_H2_STREAM_STATE_CLOSING_RX ) ) { 16 0 : return; 17 0 : } 18 : 19 18 : do { 20 : /* Calculate how much we can send in this frame */ 21 18 : long const rem_sz = (long)tx_op->chunk_sz; 22 18 : long const buf_spc = (long)fd_h2_rbuf_free_sz( rbuf_tx ) - (long)sizeof(fd_h2_frame_hdr_t); 23 18 : long const frame_max = (long)conn->peer_settings.max_frame_size; 24 : 25 18 : long payload_sz = fd_long_min( quota, rem_sz ); 26 18 : /**/ payload_sz = fd_long_min( payload_sz, buf_spc ); 27 18 : /**/ payload_sz = fd_long_min( payload_sz, frame_max ); 28 18 : if( FD_UNLIKELY( payload_sz<=0L ) ) break; 29 9 : long const next_rem_sz = rem_sz-payload_sz; 30 : 31 : /* END_STREAM flag */ 32 9 : uint flags = 0U; 33 9 : if( (next_rem_sz==0) & (!!tx_op->fin) ) { 34 9 : flags |= FD_H2_FLAG_END_STREAM; 35 9 : fd_h2_stream_close_tx( stream, conn ); 36 9 : } 37 : 38 9 : fd_h2_tx_prepare( conn, rbuf_tx, FD_H2_FRAME_TYPE_DATA, flags, stream->stream_id ); 39 9 : fd_h2_rbuf_push( rbuf_tx, tx_op->chunk, (ulong)payload_sz ); 40 9 : fd_h2_tx_commit( conn, rbuf_tx ); 41 : 42 9 : tx_op->chunk = (void *)( (ulong)tx_op->chunk + (ulong)payload_sz ); 43 9 : tx_op->chunk_sz = (ulong)next_rem_sz; 44 9 : conn->tx_wnd -= (uint)payload_sz; 45 9 : stream->tx_wnd -= (uint)payload_sz; 46 9 : quota -= payload_sz; 47 9 : } while( quota ); 48 9 : }