]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
clean up the requests on fr_worker_destroy()
authorAlan T. DeKok <aland@freeradius.org>
Tue, 25 Jul 2017 19:01:43 +0000 (15:01 -0400)
committerAlan T. DeKok <aland@freeradius.org>
Tue, 25 Jul 2017 19:53:04 +0000 (15:53 -0400)
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.

src/lib/io/worker.c

index 6bcc060b3fd992731e6ac5c27e2c7e22de470f60..21aa77439830f7ec50e461a516c4fc8499b071cd 100644 (file)
@@ -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.