From: Alan T. DeKok Date: Tue, 25 Jul 2017 19:01:43 +0000 (-0400) Subject: clean up the requests on fr_worker_destroy() X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=1302a27f744626c4686af47b57d82d7993ca26fa;p=thirdparty%2Ffreeradius-server.git clean up the requests on fr_worker_destroy() We still need to check ordering of network / worker deletion, as they call each other via RPC messages. And we need a way to destroy all requests which came from a particular network thread. We probably also need to get rid of FR_IO_ACTION_DONE, as it isn't used anywhere. Instead, just rely on the talloc destructors to clean up timers, FD events, etc. --- diff --git a/src/lib/io/worker.c b/src/lib/io/worker.c index 6bcc060b3fd..21aa7743983 100644 --- a/src/lib/io/worker.c +++ b/src/lib/io/worker.c @@ -557,7 +557,8 @@ static void fr_worker_check_timeouts(fr_worker_t *worker, fr_time_t now) } /* - * Check the "runnable" queue for old requests. + * Look at the oldest requests, and see if they need to + * be deleted. */ while ((entry = FR_DLIST_TAIL(worker->time_order)) != NULL) { REQUEST *request; @@ -974,6 +975,8 @@ void fr_worker_destroy(fr_worker_t *worker) { // int i; fr_channel_data_t *cd; + fr_dlist_t *entry; + REQUEST *request; // WORKER_VERIFY; @@ -993,6 +996,44 @@ void fr_worker_destroy(fr_worker_t *worker) fr_message_done(&cd->m); } + /* + * Remove the requests from the "runnable" queue. + */ + while ((request = fr_heap_pop(worker->runnable)) != NULL) { + fr_dlist_remove(&request->async->time_order); + talloc_free(request); + } + + /* + * Destroy all of the active requests. These are ones + * which are still waiting for timers or file descriptor + * events. + */ + while ((entry = FR_DLIST_TAIL(worker->time_order)) != NULL) { + fr_async_t *async; + + async = fr_ptr_to_type(fr_async_t, time_order, entry); + request = talloc_parent(async); + + fr_dlist_remove(&request->async->time_order); + talloc_free(request); + } + + /* + * Destroy requests which are unresponsive. + */ + for (entry = FR_DLIST_FIRST(worker->waiting_to_die); + entry != NULL; + entry = FR_DLIST_NEXT(worker->waiting_to_die, entry)) { + fr_async_t *async; + + async = fr_ptr_to_type(fr_async_t, time_order, entry); + request = talloc_parent(async); + + fr_dlist_remove(&request->async->time_order); + talloc_free(request); + } + #if 0 /* * Signal the channels that we're closing.