[multiple] perf: simplify chunkqueue_get_memory()
This commit is contained in:
parent
f512bfa4af
commit
88ee73d0a2
61
src/chunk.c
61
src/chunk.c
|
@ -383,61 +383,24 @@ void chunkqueue_append_buffer_commit(chunkqueue *cq) {
|
|||
}
|
||||
|
||||
|
||||
void chunkqueue_get_memory(chunkqueue *cq, char **mem, size_t *len, size_t min_size, size_t alloc_size) {
|
||||
static const size_t REALLOC_MAX_SIZE = 256;
|
||||
chunk *c;
|
||||
char * chunkqueue_get_memory(chunkqueue *cq, size_t *len) {
|
||||
size_t sz = *len ? *len : (chunk_buf_sz >> 1);
|
||||
buffer *b;
|
||||
char *dummy_mem;
|
||||
size_t dummy_len;
|
||||
|
||||
force_assert(NULL != cq);
|
||||
if (NULL == mem) mem = &dummy_mem;
|
||||
if (NULL == len) len = &dummy_len;
|
||||
|
||||
/* default values: */
|
||||
if (0 == min_size) min_size = 1024;
|
||||
if (0 == alloc_size) alloc_size = 4095;
|
||||
if (alloc_size < min_size) alloc_size = min_size;
|
||||
|
||||
if (NULL != cq->last && MEM_CHUNK == cq->last->type) {
|
||||
size_t have;
|
||||
|
||||
b = cq->last->mem;
|
||||
have = buffer_string_space(b);
|
||||
|
||||
/* unused buffer: allocate space */
|
||||
if (buffer_string_is_empty(b)) {
|
||||
buffer_string_prepare_copy(b, alloc_size);
|
||||
have = buffer_string_space(b);
|
||||
}
|
||||
/* if buffer is really small just make it bigger */
|
||||
else if (have < min_size && b->size <= REALLOC_MAX_SIZE) {
|
||||
size_t cur_len = buffer_string_length(b);
|
||||
size_t new_size = cur_len + min_size, append;
|
||||
if (new_size < alloc_size) new_size = alloc_size;
|
||||
|
||||
append = new_size - cur_len;
|
||||
if (append >= min_size) {
|
||||
buffer_string_prepare_append(b, append);
|
||||
have = buffer_string_space(b);
|
||||
}
|
||||
}
|
||||
|
||||
chunk *c = cq->last;
|
||||
if (NULL != c && MEM_CHUNK == c->type) {
|
||||
/* return pointer into existing buffer if large enough */
|
||||
if (have >= min_size) {
|
||||
*mem = b->ptr + buffer_string_length(b);
|
||||
*len = have;
|
||||
return;
|
||||
size_t avail = buffer_string_space(c->mem);
|
||||
if (avail >= sz) {
|
||||
*len = avail;
|
||||
b = c->mem;
|
||||
return b->ptr + buffer_string_length(b);
|
||||
}
|
||||
}
|
||||
|
||||
/* allocate new chunk */
|
||||
c = chunkqueue_append_mem_chunk(cq);
|
||||
b = c->mem;
|
||||
buffer_string_prepare_append(b, alloc_size);
|
||||
|
||||
*mem = b->ptr;
|
||||
b = chunkqueue_append_buffer_open_sz(cq, sz);
|
||||
*len = buffer_string_space(b);
|
||||
return b->ptr;
|
||||
}
|
||||
|
||||
void chunkqueue_use_memory(chunkqueue *cq, size_t len) {
|
||||
|
@ -454,7 +417,7 @@ void chunkqueue_use_memory(chunkqueue *cq, size_t len) {
|
|||
/* unused buffer: can't remove chunk easily from
|
||||
* end of list, so just reset the buffer
|
||||
*/
|
||||
buffer_reset(b);
|
||||
buffer_string_set_length(b, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
13
src/chunk.h
13
src/chunk.h
|
@ -73,18 +73,15 @@ struct server; /*(declaration)*/
|
|||
int chunkqueue_append_mem_to_tempfile(struct server *srv, chunkqueue *cq, const char *mem, size_t len);
|
||||
|
||||
/* functions to handle buffers to read into: */
|
||||
/* return a pointer to a buffer in *mem with size *len;
|
||||
* it should be at least min_size big, and use alloc_size if
|
||||
* new memory is allocated.
|
||||
/* obtain/reserve memory in chunkqueue at least len (input) size,
|
||||
* return pointer to memory with len (output) available for use
|
||||
* modifying the chunkqueue invalidates the memory area.
|
||||
* should always be followed by chunkqueue_get_memory(),
|
||||
* even if nothing was read.
|
||||
* pass 0 for min_size/alloc_size for default values
|
||||
*/
|
||||
void chunkqueue_get_memory(chunkqueue *cq, char **mem, size_t *len, size_t min_size, size_t alloc_size);
|
||||
/* append first len bytes of the memory queried with
|
||||
* chunkqueue_get_memory to the chunkqueue
|
||||
* pass 0 in len for mem at least half of chunk_buf_sz
|
||||
*/
|
||||
char * chunkqueue_get_memory(chunkqueue *cq, size_t *len);
|
||||
/* commit len bytes of mem obtained from chunkqueue_get_memory() */
|
||||
void chunkqueue_use_memory(chunkqueue *cq, size_t len);
|
||||
|
||||
/* mark first "len" bytes as written (incrementing chunk offsets)
|
||||
|
|
|
@ -959,22 +959,20 @@ static int connection_read_cq(server *srv, connection *con, chunkqueue *cq, off_
|
|||
int len;
|
||||
char *mem = NULL;
|
||||
size_t mem_len = 0;
|
||||
int toread;
|
||||
force_assert(cq == con->read_queue); /*(code transform assumption; minimize diff)*/
|
||||
force_assert(max_bytes == MAX_READ_LIMIT); /*(code transform assumption; minimize diff)*/
|
||||
|
||||
/* default size for chunks is 4kb; only use bigger chunks if FIONREAD tells
|
||||
* us more than 4kb is available
|
||||
* if FIONREAD doesn't signal a big chunk we fill the previous buffer
|
||||
* if it has >= 1kb free
|
||||
/* check avail data to read and obtain memory into which to read
|
||||
* fill previous chunk if it has sufficient space
|
||||
* (use mem_len=0 to obtain large buffer at least half of chunk_buf_sz)
|
||||
*/
|
||||
if (0 != fdevent_ioctl_fionread(con->fd, S_IFSOCK, &toread) || toread < 4096) {
|
||||
toread = 4095;
|
||||
{
|
||||
int frd;
|
||||
if (0 == fdevent_ioctl_fionread(con->fd, S_IFSOCK, &frd)) {
|
||||
mem_len = (frd < MAX_READ_LIMIT) ? (size_t)frd : MAX_READ_LIMIT;
|
||||
}
|
||||
}
|
||||
else if (toread > MAX_READ_LIMIT) {
|
||||
toread = MAX_READ_LIMIT;
|
||||
}
|
||||
chunkqueue_get_memory(con->read_queue, &mem, &mem_len, 0, toread);
|
||||
mem = chunkqueue_get_memory(con->read_queue, &mem_len);
|
||||
|
||||
#if defined(__WIN32)
|
||||
len = recv(con->fd, mem, mem_len, 0);
|
||||
|
|
|
@ -1430,8 +1430,9 @@ connection_read_cq_ssl (server *srv, connection *con,
|
|||
|
||||
ERR_clear_error();
|
||||
do {
|
||||
chunkqueue_get_memory(con->read_queue, &mem, &mem_len, 0,
|
||||
SSL_pending(hctx->ssl));
|
||||
len = SSL_pending(hctx->ssl);
|
||||
mem_len = len < 2048 ? 2048 : (size_t)len;
|
||||
mem = chunkqueue_get_memory(con->read_queue, &mem_len);
|
||||
#if 0
|
||||
/* overwrite everything with 0 */
|
||||
memset(mem, 0, mem_len);
|
||||
|
|
|
@ -938,17 +938,11 @@ static int send_ietf_00(handler_ctx *hctx, mod_wstunnel_frame_type_t type, const
|
|||
http_chunk_append_mem(srv, con, &head, 1);
|
||||
len = 4*(siz/3)+4+1;
|
||||
/* avoid accumulating too much data in memory; send to tmpfile */
|
||||
#if 0
|
||||
chunkqueue_get_memory(con->write_queue, &mem, &len, len, 0);
|
||||
len=li_to_base64(mem,len,(unsigned char *)payload,siz,BASE64_STANDARD);
|
||||
chunkqueue_use_memory(con->write_queue, len);
|
||||
#else
|
||||
mem = malloc(len);
|
||||
force_assert(mem);
|
||||
len=li_to_base64(mem,len,(unsigned char *)payload,siz,BASE64_STANDARD);
|
||||
http_chunk_append_mem(srv, con, mem, len);
|
||||
free(mem);
|
||||
#endif
|
||||
http_chunk_append_mem(srv, con, &tail, 1);
|
||||
len += 2;
|
||||
break;
|
||||
|
@ -1029,13 +1023,8 @@ static int recv_ietf_00(handler_ctx *hctx) {
|
|||
i++;
|
||||
if (hctx->frame.type == MOD_WEBSOCKET_FRAME_TYPE_TEXT
|
||||
&& !buffer_is_empty(payload)) {
|
||||
size_t len;
|
||||
hctx->frame.ctl.siz = 0;
|
||||
len = buffer_string_length(payload);
|
||||
chunkqueue_get_memory(hctx->gw.wb, &mem, &len, len, 0);
|
||||
len = buffer_string_length(payload);
|
||||
memcpy(mem, payload->ptr, len);
|
||||
chunkqueue_use_memory(hctx->gw.wb, len);
|
||||
chunkqueue_append_mem(hctx->gw.wb, CONST_BUF_LEN(payload));
|
||||
buffer_reset(payload);
|
||||
}
|
||||
else {
|
||||
|
@ -1044,7 +1033,7 @@ static int recv_ietf_00(handler_ctx *hctx) {
|
|||
buffer *b;
|
||||
size_t len = buffer_string_length(payload);
|
||||
len = (len+3)/4*3+1;
|
||||
chunkqueue_get_memory(hctx->gw.wb, &mem, &len, len, 0);
|
||||
chunkqueue_get_memory(hctx->gw.wb, &len);
|
||||
b = hctx->gw.wb->last->mem;
|
||||
len = buffer_string_length(b);
|
||||
DEBUG_LOG(MOD_WEBSOCKET_LOG_DEBUG, "ss",
|
||||
|
@ -1313,14 +1302,8 @@ static int recv_rfc_6455(handler_ctx *hctx) {
|
|||
case MOD_WEBSOCKET_FRAME_TYPE_TEXT:
|
||||
case MOD_WEBSOCKET_FRAME_TYPE_BIN:
|
||||
{
|
||||
char *mem;
|
||||
size_t len;
|
||||
unmask_payload(hctx);
|
||||
len = buffer_string_length(payload);
|
||||
chunkqueue_get_memory(hctx->gw.wb, &mem, &len, len, 0);
|
||||
len = buffer_string_length(payload);
|
||||
memcpy(mem, payload->ptr, len);
|
||||
chunkqueue_use_memory(hctx->gw.wb, len);
|
||||
chunkqueue_append_mem(hctx->gw.wb, CONST_BUF_LEN(payload));
|
||||
buffer_reset(payload);
|
||||
break;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue