From: Marek VavruĊĦa Date: Wed, 8 Jul 2015 16:09:59 +0000 (+0200) Subject: daemon/worker: fixed leak X-Git-Tag: v1.0.0-beta1~83^2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=6b07f80dc29b89d1ae9d6952f1b95a83042b2ac0;p=thirdparty%2Fknot-resolver.git daemon/worker: fixed leak --- diff --git a/daemon/worker.c b/daemon/worker.c index 3df6c805d..58ab23e19 100644 --- a/daemon/worker.c +++ b/daemon/worker.c @@ -226,10 +226,13 @@ static void on_write(uv_write_t *req, int status) static int qr_task_send(struct qr_task *task, uv_handle_t *handle, struct sockaddr *addr, knot_pkt_t *pkt) { int ret = 0; - struct ioreq *req = ioreq_take(task->worker); - if (!handle || !req) { + if (!handle) { return qr_task_on_send(task, kr_error(EIO)); } + struct ioreq *req = ioreq_take(task->worker); + if (!req) { + return qr_task_on_send(task, kr_error(ENOMEM)); + } if (handle->type == UV_UDP) { uv_buf_t buf = { (char *)pkt->wire, pkt->size }; req->as.send.data = task; @@ -247,6 +250,9 @@ static int qr_task_send(struct qr_task *task, uv_handle_t *handle, struct sockad if (handle != task->source.handle) task->worker->stats.tcp += 1; } + if (ret != 0) { + ioreq_release(task->worker, req); + } return ret; } @@ -255,8 +261,10 @@ static void on_connect(uv_connect_t *req, int status) struct qr_task *task = req->data; if (status == 0) { qr_task_send(task, (uv_handle_t *)req->handle, NULL, task->next_query); + ioreq_release(task->worker, (struct ioreq *)req); + } else { /* Must not recycle, as 'task' may be freed. */ + free(req); } - ioreq_release(task->worker, (struct ioreq *)req); } static int qr_task_finalize(struct qr_task *task, int state)