]> git.ipfire.org Git - thirdparty/tor.git/commitdiff
New testcase exposing bug during threadpool shutdown
authorSebastian Hahn <sebastian@torproject.org>
Thu, 20 Aug 2015 17:57:08 +0000 (19:57 +0200)
committerSebastian Hahn <sebastian@torproject.org>
Thu, 20 Aug 2015 18:00:05 +0000 (20:00 +0200)
We don't want to accept any work after one of our worker functions has
returned WQ_RPL_SHUTDOWN. This testcase currently fails, because we do
not actually stop any of the worker threads.

src/test/test_workqueue.c

index 7f206420410e827848709a9a4ac9e13224b2df45..1d2cd940c3756cc4678bcd587ae7e1638cb7855c 100644 (file)
@@ -124,6 +124,14 @@ workqueue_do_ecdh(void *state, void *work)
   return WQ_RPL_REPLY;
 }
 
+static int
+workqueue_shutdown_error(void *state, void *work)
+{
+  (void)state;
+  (void)work;
+  return WQ_RPL_REPLY;
+}
+
 static void *
 new_state(void *arg)
 {
@@ -156,6 +164,7 @@ static int n_sent = 0;
 static int rsa_sent = 0;
 static int ecdh_sent = 0;
 static int n_received = 0;
+static int no_shutdown = 0;
 
 #ifdef TRACK_RESPONSES
 bitarray_t *received;
@@ -174,6 +183,14 @@ handle_reply(void *arg)
   ++n_received;
 }
 
+/* This should never get called. */
+static void
+handle_reply_shutdown(void *arg)
+{
+  (void)arg;
+  no_shutdown = 1;
+}
+
 static workqueue_entry_t *
 add_work(threadpool_t *tp)
 {
@@ -288,6 +305,8 @@ replysock_readable_cb(tor_socket_t sock, short what, void *arg)
     shutting_down = 1;
     threadpool_queue_update(tp, NULL,
                              workqueue_do_shutdown, NULL, NULL);
+    // Anything we add after starting the shutdown must not be executed.
+    threadpool_queue_work(tp, workqueue_shutdown_error, handle_reply_shutdown, NULL);
     {
       struct timeval limit = { 2, 0 };
       tor_event_base_loopexit(tor_libevent_get_base(), &limit);
@@ -416,6 +435,9 @@ main(int argc, char **argv)
     printf("%d+%d vs %d\n", n_received, n_successful_cancel, n_sent);
     puts("FAIL");
     return 1;
+  } else if (no_shutdown) {
+    puts("Accepted work after shutdown\n");
+    puts("FAIL");
   } else {
     puts("OK");
     return 0;