Browse Source

[multiple] perf: simplify chunkqueue_get_memory()

personal/stbuehler/fix-fdevent
Glenn Strauss 4 years ago
parent
commit
88ee73d0a2
  1. 61
      src/chunk.c
  2. 13
      src/chunk.h
  3. 20
      src/connections.c
  4. 5
      src/mod_openssl.c
  5. 23
      src/mod_wstunnel.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

@ -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)

20
src/connections.c

@ -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;
}
else if (toread > MAX_READ_LIMIT) {
toread = MAX_READ_LIMIT;
{
int frd;
if (0 == fdevent_ioctl_fionread(con->fd, S_IFSOCK, &frd)) {
mem_len = (frd < MAX_READ_LIMIT) ? (size_t)frd : 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);

5
src/mod_openssl.c

@ -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);

23
src/mod_wstunnel.c

@ -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…
Cancel
Save