[core] h2_send_cqdata() returns how much data sent

This commit is contained in:
Glenn Strauss 2021-09-29 09:22:28 -04:00
parent 042622c8c1
commit 62dc817caf
3 changed files with 32 additions and 30 deletions

View File

@ -1241,7 +1241,6 @@ connection_state_machine_h2 (request_st * const h2r, connection * const con)
off_t max_bytes = con->is_writable > 0
? connection_write_throttle(con, MAX_WRITE_LIMIT)
: 0;
const off_t fsize = (off_t)h2c->s_max_frame_size;
const off_t cqlen = chunkqueue_length(con->write_queue);
if (cqlen > 8192 && max_bytes > 65536) max_bytes = 65536;
max_bytes -= cqlen;
@ -1268,30 +1267,25 @@ connection_state_machine_h2 (request_st * const h2r, connection * const con)
connection_state_machine_loop(r, con);
if (r->resp_header_len && !chunkqueue_is_empty(&r->write_queue)
&& max_bytes
&& (r->resp_body_finished
|| (r->conf.stream_response_body
& (FDEVENT_STREAM_RESPONSE
|FDEVENT_STREAM_RESPONSE_BUFMIN)))) {
chunkqueue * const cq = &r->write_queue;
off_t avail = chunkqueue_length(cq);
if (avail > max_bytes) avail = max_bytes;
if (avail > fsize) avail = fsize;
if (avail > r->h2_swin) avail = r->h2_swin;
if (avail > h2r->h2_swin) avail = h2r->h2_swin;
uint32_t dlen = (uint32_t)max_bytes;
dlen = h2_send_cqdata(r, con, &r->write_queue, dlen);
max_bytes -= (off_t)dlen;
if (avail > 0) {
max_bytes -= avail;
h2_send_cqdata(r, con, cq, (uint32_t)avail);
if (chunkqueue_is_empty(&r->write_queue)) {
if (r->resp_body_finished) {
connection_set_state(r, CON_STATE_RESPONSE_END);
if (__builtin_expect( (r->conf.log_state_handling), 0))
connection_state_machine_loop(r, con);
}
}
if (r->resp_body_finished && chunkqueue_is_empty(cq)) {
connection_set_state(r, CON_STATE_RESPONSE_END);
if (r->conf.log_state_handling)
connection_state_machine_loop(r, con);
}
else if (avail) /*(do not spin if swin empty window)*/
resched |= (!chunkqueue_is_empty(cq));
else if (dlen) /*(do not spin if swin empty window)*/
resched |= 1; /*(!chunkqueue_is_empty(&r->write_queue))*/
}
#if 0

View File

@ -2315,7 +2315,7 @@ h2_send_cqheaders (request_st * const r, connection * const con)
#if 0
void
uint32_t
h2_send_data (request_st * const r, connection * const con, const char *data, uint32_t dlen)
{
/* Note: dlen should be <= MAX_WRITE_LIMIT in order to share resources */
@ -2340,11 +2340,11 @@ h2_send_data (request_st * const r, connection * const con, const char *data, ui
/* adjust stream and connection windows */
/*assert(dlen <= INT32_MAX);*//* dlen should be <= MAX_WRITE_LIMIT */
request_st * const h2r = &con->request;
if (r->h2_swin < 0) return;
if (h2r->h2_swin < 0) return;
if (r->h2_swin < 0) return 0;
if (h2r->h2_swin < 0) return 0;
if ((int32_t)dlen > r->h2_swin) dlen = (uint32_t)r->h2_swin;
if ((int32_t)dlen > h2r->h2_swin) dlen = (uint32_t)h2r->h2_swin;
if (0 == dlen) return;
if (0 == dlen) return 0;
r->h2_swin -= (int32_t)dlen;
h2r->h2_swin -= (int32_t)dlen;
@ -2362,6 +2362,7 @@ h2_send_data (request_st * const r, connection * const con, const char *data, ui
char * restrict ptr = b->ptr;
h2con * const h2c = con->h2;
const uint32_t fsize = h2c->s_max_frame_size;
uint32_t sent = 0;
do {
const uint32_t len = dlen < fsize ? dlen : fsize;
dataframe.c[3] = (len >> 16) & 0xFF; /*(off +3 to skip over align pad)*/
@ -2377,16 +2378,18 @@ h2_send_data (request_st * const r, connection * const con, const char *data, ui
ptr += len + sizeof(dataframe)-3;
#endif
data += len;
sent += len;
dlen -= len;
} while (dlen);
buffer_truncate(b, (uint32_t)(ptr - b->ptr));
chunkqueue_append_buffer_commit(con->write_queue);
return sent;
}
#endif
void
uint32_t
h2_send_cqdata (request_st * const r, connection * const con, chunkqueue * const cq, uint32_t dlen)
{
/* Note: dlen should be <= MAX_WRITE_LIMIT in order to share resources */
@ -2411,13 +2414,13 @@ h2_send_cqdata (request_st * const r, connection * const con, chunkqueue * const
/* adjust stream and connection windows */
/*assert(dlen <= INT32_MAX);*//* dlen should be <= MAX_WRITE_LIMIT */
request_st * const h2r = &con->request;
if (r->h2_swin < 0) return;
if (h2r->h2_swin < 0) return;
if (r->h2_swin < 0) return 0;
if (h2r->h2_swin < 0) return 0;
if ((int32_t)dlen > r->h2_swin) dlen = (uint32_t)r->h2_swin;
if ((int32_t)dlen > h2r->h2_swin) dlen = (uint32_t)h2r->h2_swin;
if (0 == dlen) return;
r->h2_swin -= (int32_t)dlen;
h2r->h2_swin -= (int32_t)dlen;
const uint32_t cqlen = (uint32_t)chunkqueue_length(cq);
if (dlen > cqlen) dlen = cqlen;
if (0 == dlen) return 0;
/* XXX: future: should have an interface which processes chunkqueue
* and takes string refs to mmap FILE_CHUNK to avoid extra copying
@ -2425,16 +2428,21 @@ h2_send_cqdata (request_st * const r, connection * const con, chunkqueue * const
h2con * const h2c = con->h2;
const uint32_t fsize = h2c->s_max_frame_size;
uint32_t sent = 0;
do {
const uint32_t len = dlen < fsize ? dlen : fsize;
dlen -= len;
sent += len;
dataframe.c[3] = (len >> 16) & 0xFF; /*(off +3 to skip over align pad)*/
dataframe.c[4] = (len >> 8) & 0xFF;
dataframe.c[5] = (len ) & 0xFF;
chunkqueue_append_mem(con->write_queue, /*(+3 to skip over align pad)*/
(const char *)dataframe.c+3, sizeof(dataframe)-3);
chunkqueue_steal(con->write_queue, cq, (off_t)len);
dlen -= len;
} while (dlen);
r->h2_swin -= (int32_t)sent;
h2r->h2_swin -= (int32_t)sent;
return sent;
}

View File

@ -101,7 +101,7 @@ void h2_send_100_continue (request_st *r, connection *con);
void h2_send_headers (request_st *r, connection *con);
void h2_send_cqdata (request_st *r, connection *con, struct chunkqueue *cq, uint32_t dlen);
uint32_t h2_send_cqdata (request_st *r, connection *con, struct chunkqueue *cq, uint32_t dlen);
void h2_send_end_stream (request_st *r, connection *con);