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