diff --git a/include/lighttpd/worker.h b/include/lighttpd/worker.h index 9b7f747..c434092 100644 --- a/include/lighttpd/worker.h +++ b/include/lighttpd/worker.h @@ -117,7 +117,7 @@ struct liWorker { liStatCache *stat_cache; - GByteArray *network_read_buf; /** internal temporary buffer for network.c */ + liBuffer *network_read_buf; /** available buffer - steal it if you need it, can be NULL. refcount must be 1, no other references. */ }; LI_API liWorker* li_worker_new(liServer *srv, struct ev_loop *loop); diff --git a/src/main/connection.c b/src/main/connection.c index 48a14c9..cd5e042 100644 --- a/src/main/connection.c +++ b/src/main/connection.c @@ -294,12 +294,25 @@ static G_GNUC_WARN_UNUSED_RESULT gboolean connection_try_read(liConnection *con) goffset transferred; transferred = con->raw_in->length; + if (NULL == con->raw_in_buffer && NULL != con->wrk->network_read_buf) { + /* reuse worker buf if needed */ + con->raw_in_buffer = con->wrk->network_read_buf; + con->wrk->network_read_buf = NULL; + } + if (con->srv_sock->read_cb) { res = con->srv_sock->read_cb(con); } else { res = li_network_read(con->mainvr, con->sock_watcher.fd, con->raw_in, &con->raw_in_buffer); } + if (NULL == con->wrk->network_read_buf && NULL != con->raw_in_buffer + && 1 == g_atomic_int_get(&con->raw_in_buffer->refcount)) { + /* move buffer back to worker if we didn't use it */ + con->wrk->network_read_buf = con->raw_in_buffer; + con->raw_in_buffer = NULL; + } + transferred = con->raw_in->length - transferred; if (transferred > 0) connection_update_io_timeout(con); diff --git a/src/main/worker.c b/src/main/worker.c index 6441f6c..bd4c282 100644 --- a/src/main/worker.c +++ b/src/main/worker.c @@ -426,7 +426,7 @@ liWorker* li_worker_new(liServer *srv, struct ev_loop *loop) { wrk->tasklets = li_tasklet_pool_new(wrk->loop, srv->tasklet_pool_threads); - wrk->network_read_buf = g_byte_array_sized_new(0); + wrk->network_read_buf = NULL; return wrk; } @@ -492,7 +492,7 @@ void li_worker_free(liWorker *wrk) { wrk->L = NULL; #endif - g_byte_array_free(wrk->network_read_buf, TRUE); + li_buffer_release(wrk->network_read_buf); g_slice_free(liWorker, wrk); }