summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGlenn Strauss <gstrauss@gluelogic.com>2021-09-16 04:24:29 -0400
committerGlenn Strauss <gstrauss@gluelogic.com>2021-09-16 04:40:12 -0400
commit0b56c16a8b7b0bf110e575af1d1de8ced2436025 (patch)
treea6a31fff85603d4267421b31487f29cf49ee3fd0
parent94053349c23ecfd5e8d426e5f656a469ef65c972 (diff)
downloadlighttpd-git-0b56c16a8b7b0bf110e575af1d1de8ced2436025.tar.gz
[core] reduce oversized mem alloc for backends
reduce oversized memory allocations when reading from backends: avoid extra power-2 allocation for 1 byte ('\0') when data available to read is exactly power-2
-rw-r--r--src/chunk.c14
-rw-r--r--src/http-header-glue.c2
2 files changed, 10 insertions, 6 deletions
diff --git a/src/chunk.c b/src/chunk.c
index 43ee14a1..b88c2636 100644
--- a/src/chunk.c
+++ b/src/chunk.c
@@ -144,7 +144,7 @@ static void chunk_push_oversized(chunk * const c, const size_t sz) {
}
__attribute_returns_nonnull__
-static buffer * chunk_buffer_acquire_sz(size_t sz) {
+static buffer * chunk_buffer_acquire_sz(const size_t sz) {
chunk *c;
buffer *b;
if (sz <= (chunk_buf_sz|1)) {
@@ -159,11 +159,15 @@ static buffer * chunk_buffer_acquire_sz(size_t sz) {
* (and if doing so, might replace chunks_oversized_n) */
}
else {
- /*(round up to nearest chunk_buf_sz)*/
- sz = (sz + (chunk_buf_sz-1)) & ~(chunk_buf_sz-1);
c = chunk_pop_oversized(sz);
- if (NULL == c)
- c = chunk_init(sz);
+ if (NULL == c) {
+ /*(round up to nearest chunk_buf_sz)*/
+ /* NB: round down power-2 + 1 to avoid excess allocation
+ * (sz & ~1uL) relies on buffer_realloc() adding +1 *and* on callers
+ * of this func never passing power-2 + 1 sz unless the direct caller
+ * adds +1 for '\0', as is done in chunk_buffer_prepare_append() */
+ c = chunk_init(((sz & ~1uL)+(chunk_buf_sz-1)) & ~(chunk_buf_sz-1));
+ }
}
c->next = chunk_buffers;
chunk_buffers = c;
diff --git a/src/http-header-glue.c b/src/http-header-glue.c
index 38a3a76d..a70b510c 100644
--- a/src/http-header-glue.c
+++ b/src/http-header-glue.c
@@ -1207,7 +1207,7 @@ handler_t http_response_read(request_st * const r, http_response_opts * const op
if (avail < toread) {
/*(add avail+toread to reduce allocations when ioctl EOPNOTSUPP)*/
- avail = avail ? avail - 1 + toread : toread;
+ avail = toread < MAX_READ_LIMIT && avail ? avail-1+toread : toread;
avail = chunk_buffer_prepare_append(b, avail);
}