[core] h2_send_cqdata() returns how much data sent
This commit is contained in:
parent
042622c8c1
commit
62dc817caf
|
@ -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
|
||||
|
|
30
src/h2.c
30
src/h2.c
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
|
2
src/h2.h
2
src/h2.h
|
@ -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);
|
||||
|
||||
|
|
Loading…
Reference in New Issue