nghttp2_bufs: Add chunk_keep to specify the number of buffers to keep on reset

This commit is contained in:
Tatsuhiro Tsujikawa 2014-03-16 15:58:21 +09:00
parent fbfa3adc42
commit 68b392817b
5 changed files with 65 additions and 19 deletions

View File

@ -131,11 +131,17 @@ int nghttp2_bufs_init(nghttp2_bufs *bufs, size_t chunk_length,
int nghttp2_bufs_init2(nghttp2_bufs *bufs, size_t chunk_length, int nghttp2_bufs_init2(nghttp2_bufs *bufs, size_t chunk_length,
size_t max_chunk, size_t offset) size_t max_chunk, size_t offset)
{
return nghttp2_bufs_init3(bufs, chunk_length, max_chunk, max_chunk, offset);
}
int nghttp2_bufs_init3(nghttp2_bufs *bufs, size_t chunk_length,
size_t max_chunk, size_t chunk_keep, size_t offset)
{ {
int rv; int rv;
nghttp2_buf_chain *chain; nghttp2_buf_chain *chain;
if(max_chunk == 0 || chunk_length < offset) { if(chunk_keep == 0 || max_chunk < chunk_keep || chunk_length < offset) {
return NGHTTP2_ERR_INVALID_ARGUMENT; return NGHTTP2_ERR_INVALID_ARGUMENT;
} }
@ -152,7 +158,9 @@ int nghttp2_bufs_init2(nghttp2_bufs *bufs, size_t chunk_length,
nghttp2_buf_shift_right(&bufs->cur->buf, offset); nghttp2_buf_shift_right(&bufs->cur->buf, offset);
bufs->chunk_length = chunk_length; bufs->chunk_length = chunk_length;
bufs->chunk_left = max_chunk - 1; bufs->chunk_used = 1;
bufs->max_chunk = max_chunk;
bufs->chunk_keep = chunk_keep;
return 0; return 0;
} }
@ -199,7 +207,7 @@ ssize_t nghttp2_bufs_len(nghttp2_bufs *bufs)
static int nghttp2_bufs_avail(nghttp2_bufs *bufs) static int nghttp2_bufs_avail(nghttp2_bufs *bufs)
{ {
return nghttp2_buf_avail(&bufs->cur->buf) + return nghttp2_buf_avail(&bufs->cur->buf) +
(bufs->chunk_length - bufs->offset) * bufs->chunk_left; (bufs->chunk_length - bufs->offset) * (bufs->max_chunk - bufs->chunk_used);
} }
static int nghttp2_bufs_alloc_chain(nghttp2_bufs *bufs) static int nghttp2_bufs_alloc_chain(nghttp2_bufs *bufs)
@ -213,7 +221,7 @@ static int nghttp2_bufs_alloc_chain(nghttp2_bufs *bufs)
return 0; return 0;
} }
if(bufs->chunk_left == 0) { if(bufs->max_chunk == bufs->chunk_used) {
return NGHTTP2_ERR_BUFFER_ERROR; return NGHTTP2_ERR_BUFFER_ERROR;
} }
@ -226,7 +234,7 @@ static int nghttp2_bufs_alloc_chain(nghttp2_bufs *bufs)
"new buffer %zu bytes allocated for bufs %p, left %zu\n", "new buffer %zu bytes allocated for bufs %p, left %zu\n",
bufs->chunk_length, bufs, bufs->chunk_left)); bufs->chunk_length, bufs, bufs->chunk_left));
--bufs->chunk_left; ++bufs->chunk_used;
bufs->cur->next = chain; bufs->cur->next = chain;
bufs->cur = chain; bufs->cur = chain;
@ -382,11 +390,33 @@ ssize_t nghttp2_bufs_remove(nghttp2_bufs *bufs, uint8_t **out)
void nghttp2_bufs_reset(nghttp2_bufs *bufs) void nghttp2_bufs_reset(nghttp2_bufs *bufs)
{ {
nghttp2_buf_chain *chain; nghttp2_buf_chain *chain, *ci;
size_t k;
for(chain = bufs->head; chain; chain = chain->next) { k = bufs->chunk_keep;
nghttp2_buf_reset(&chain->buf);
nghttp2_buf_shift_right(&chain->buf, bufs->offset); for(ci = bufs->head; ci; ci = ci->next) {
nghttp2_buf_reset(&ci->buf);
nghttp2_buf_shift_right(&ci->buf, bufs->offset);
if(--k == 0) {
break;
}
}
if(ci) {
chain = ci->next;
ci->next = NULL;
for(ci = chain; ci;) {
chain = ci->next;
nghttp2_buf_chain_del(ci);
ci = chain;
}
bufs->chunk_used = bufs->chunk_keep;
} }
bufs->cur = bufs->head; bufs->cur = bufs->head;

View File

@ -154,7 +154,11 @@ typedef struct {
/* The buffer capacity of each buf */ /* The buffer capacity of each buf */
size_t chunk_length; size_t chunk_length;
/* The maximum number of nghttp2_buf_chain */ /* The maximum number of nghttp2_buf_chain */
size_t chunk_left; size_t max_chunk;
/* The number of nghttp2_buf_chain allocated */
size_t chunk_used;
/* The number of nghttp2_buf_chain to keep on reset */
size_t chunk_keep;
/* pos offset from begin in each buffers. On initialization and /* pos offset from begin in each buffers. On initialization and
reset, buf->pos and buf->last are positioned at buf->begin + reset, buf->pos and buf->last are positioned at buf->begin +
offset. */ offset. */
@ -168,11 +172,19 @@ typedef struct {
int nghttp2_bufs_init(nghttp2_bufs *bufs, size_t chunk_length, int nghttp2_bufs_init(nghttp2_bufs *bufs, size_t chunk_length,
size_t max_chunk); size_t max_chunk);
/*
* This is the same as calling nghttp2_bufs_init3 with the given
* arguments and chunk_keep = max_chunk.
*/
int nghttp2_bufs_init2(nghttp2_bufs *bufs, size_t chunk_length,
size_t max_chunk, size_t offset);
/* /*
* Initializes |bufs|. Each buffer size is given in the * Initializes |bufs|. Each buffer size is given in the
* |chunk_length|. The maximum number of buffers is given in the * |chunk_length|. The maximum number of buffers is given in the
* |max_chunk|. Each buffer will have bufs->pos and bufs->last shifted * |max_chunk|. On reset, first |chunk_keep| buffers are kept and
* to left by |offset| bytes on creation and reset. * remaining buffers are deleted. Each buffer will have bufs->pos and
* bufs->last shifted to left by |offset| bytes on creation and reset.
* *
* This function allocates first buffer. bufs->head and bufs->cur * This function allocates first buffer. bufs->head and bufs->cur
* will point to the first buffer after this call. * will point to the first buffer after this call.
@ -183,10 +195,11 @@ int nghttp2_bufs_init(nghttp2_bufs *bufs, size_t chunk_length,
* NGHTTP2_ERR_NOMEM * NGHTTP2_ERR_NOMEM
* Out of memory. * Out of memory.
* NGHTTP2_ERR_INVALID_ARGUMENT * NGHTTP2_ERR_INVALID_ARGUMENT
* max_chunk is 0 * chunk_keep is 0; or max_chunk < chunk_keep; or offset is too
* long.
*/ */
int nghttp2_bufs_init2(nghttp2_bufs *bufs, size_t chunk_length, int nghttp2_bufs_init3(nghttp2_bufs *bufs, size_t chunk_length,
size_t max_chunk, size_t offset); size_t max_chunk, size_t chunk_keep, size_t offset);
/* /*
* Frees any related resources to the |bufs|. * Frees any related resources to the |bufs|.

View File

@ -291,9 +291,10 @@ static int nghttp2_session_new(nghttp2_session **session_ptr,
/* 2 for PAD_HIGH and PAD_LOW. We have maximum 64KB of frame /* 2 for PAD_HIGH and PAD_LOW. We have maximum 64KB of frame
serialization buffer for transmission */ serialization buffer for transmission */
rv = nghttp2_bufs_init2(&(*session_ptr)->aob.framebufs, rv = nghttp2_bufs_init3(&(*session_ptr)->aob.framebufs,
NGHTTP2_MAX_FRAMELEN, NGHTTP2_MAX_FRAMELEN,
65536 / NGHTTP2_MAX_FRAMELEN, (1 << 17) / NGHTTP2_MAX_FRAMELEN,
(1 << 13) / NGHTTP2_MAX_FRAMELEN,
NGHTTP2_FRAME_HDLEN + 2); NGHTTP2_FRAME_HDLEN + 2);
if(rv != 0) { if(rv != 0) {
goto fail_aob_framebuf; goto fail_aob_framebuf;

View File

@ -203,7 +203,7 @@ void test_nghttp2_bufs_reset(void)
nghttp2_buf_chain *ci; nghttp2_buf_chain *ci;
ssize_t offset = 9; ssize_t offset = 9;
rv = nghttp2_bufs_init2(&bufs, 250, 3, offset); rv = nghttp2_bufs_init3(&bufs, 250, 3, 1, offset);
CU_ASSERT(0 == rv); CU_ASSERT(0 == rv);
rv = nghttp2_bufs_add(&bufs, "foo", 3); rv = nghttp2_bufs_add(&bufs, "foo", 3);
@ -227,6 +227,8 @@ void test_nghttp2_bufs_reset(void)
CU_ASSERT(ci->buf.pos == ci->buf.last); CU_ASSERT(ci->buf.pos == ci->buf.last);
} }
CU_ASSERT(bufs.head->next == NULL);
nghttp2_bufs_free(&bufs); nghttp2_bufs_free(&bufs);
} }

View File

@ -1996,7 +1996,7 @@ void test_nghttp2_session_send_headers_header_comp_error(void)
nghttp2_nv *nva; nghttp2_nv *nva;
ssize_t nvlen; ssize_t nvlen;
size_t vallen = NGHTTP2_HD_MAX_VALUE; size_t vallen = NGHTTP2_HD_MAX_VALUE;
nghttp2_nv nv[16]; nghttp2_nv nv[28];
size_t nnv = ARRLEN(nv); size_t nnv = ARRLEN(nv);
size_t i; size_t i;