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