From 3bcf541f6ac8a467e5b0a2e7ab910d67115018ef Mon Sep 17 00:00:00 2001 From: Marek Vavrusa <marek.vavrusa@nic.cz> Date: Thu, 16 Aug 2012 14:55:24 +0200 Subject: [PATCH] XFR handler is terminated by the interrupt request. This allows to clear any existing requests in the queue, preventing potential memory leaks on shutdown. refs #1976 --- src/common/evqueue.c | 7 +++++-- src/knot/server/server.c | 7 ++----- src/knot/server/xfr-handler.c | 14 ++++++++++++-- 3 files changed, 19 insertions(+), 9 deletions(-) diff --git a/src/common/evqueue.c b/src/common/evqueue.c index 76141115f3..240ced618e 100644 --- a/src/common/evqueue.c +++ b/src/common/evqueue.c @@ -126,8 +126,11 @@ void evqueue_free(evqueue_t **q) *q = 0; /* Deinitialize. */ - close(eq->fds[EVQUEUE_READFD]); - close(eq->fds[EVQUEUE_WRITEFD]); + for (int i = 0; i < 2; ++i) { + if (eq->fds[i] > -1) { + close(eq->fds[i]); + } + } free(eq); } diff --git a/src/knot/server/server.c b/src/knot/server/server.c index 4d01801cd5..06f89b5a99 100644 --- a/src/knot/server/server.c +++ b/src/knot/server/server.c @@ -651,16 +651,13 @@ void server_stop(server_t *server) { dbg_server("server: stopping server\n"); - /* Wait for XFR master. */ - xfr_stop(server->xfr_h); + /* Send termination event. */ + evsched_schedule_term(server->sched, 0); /* Interrupt XFR handler execution. */ if (server->xfr_h->interrupt) { server->xfr_h->interrupt(server->xfr_h); } - - /* Send termination event. */ - evsched_schedule_term(server->sched, 0); /* Lock RCU. */ rcu_read_lock(); diff --git a/src/knot/server/xfr-handler.c b/src/knot/server/xfr-handler.c index 9b8055ad22..6662443f30 100644 --- a/src/knot/server/xfr-handler.c +++ b/src/knot/server/xfr-handler.c @@ -51,7 +51,13 @@ void xfr_interrupt(xfrhandler_t *h) { for(unsigned i = 0; i < h->unit->size; ++i) { - evqueue_write(h->workers[i]->q, "", 1); + evqueue_t *q = h->workers[i]->q; + if (evqueue_write(q, "", 1) == 1) { + close(q->fds[EVQUEUE_WRITEFD]); + q->fds[EVQUEUE_WRITEFD] = -1; + } else { + dt_stop_id(h->unit->threads[i]); + } } } @@ -1558,7 +1564,6 @@ int xfr_worker(dthread_t *thread) fdset_begin(w->fdset, &it); int rfd_event = 0; while(nfds > 0) { - /* Check if it request. */ if (it.fd == rfd) { rfd_event = 1; /* Delay new tasks after processing. */ @@ -1605,6 +1610,11 @@ int xfr_worker(dthread_t *thread) next_sweep.tv_sec += XFR_SWEEP_INTERVAL; } } + + /* Check for interrupt request. */ + if (ret == KNOTD_ENOTRUNNING) { + break; + } } /* Stop whole unit. */ -- GitLab