Browse Source

Turn 'mainloop' into a subsystem.

We need a little refactoring for this to work, since the
initialization code for the periodic events assumes that libevent is
already initialized, which it can't be until it's configured.

This change, combined with the previous ones, lets other subsystems
declare their own periodic events, without mainloop.c having to know
about them.  Implements ticket 30293.
Nick Mathewson 6 years ago
parent
commit
6eb1b8da0a

+ 0 - 2
src/app/main/shutdown.c

@@ -18,7 +18,6 @@
 #include "app/main/shutdown.h"
 #include "app/main/subsysmgr.h"
 #include "core/mainloop/connection.h"
-#include "core/mainloop/mainloop.h"
 #include "core/mainloop/mainloop_pubsub.h"
 #include "core/or/channeltls.h"
 #include "core/or/circuitlist.h"
@@ -176,7 +175,6 @@ tor_free_all(int postfork)
   /* stuff in main.c */
 
   tor_mainloop_disconnect_pubsub();
-  tor_mainloop_free_all();
 
   if (!postfork) {
     release_lockfile();

+ 3 - 0
src/app/main/subsystem_list.c

@@ -8,6 +8,7 @@
 #include "lib/cc/compat_compiler.h"
 #include "lib/cc/torint.h"
 
+#include "core/mainloop/mainloop_sys.h"
 #include "core/or/ocirc_event_sys.h"
 #include "core/or/orconn_event_sys.h"
 #include "feature/control/btrack_sys.h"
@@ -44,6 +45,8 @@ const subsys_fns_t *tor_subsystems[] = {
   &sys_orconn_event, /* -33 */
   &sys_ocirc_event, /* -32 */
   &sys_btrack, /* -30 */
+
+  &sys_mainloop, /* 5 */
 };
 
 const unsigned n_tor_subsystems = ARRAY_LENGTH(tor_subsystems);

+ 2 - 0
src/core/include.am

@@ -24,6 +24,7 @@ LIBTOR_APP_A_SOURCES = 				\
 	src/core/mainloop/cpuworker.c		\
 	src/core/mainloop/mainloop.c		\
 	src/core/mainloop/mainloop_pubsub.c	\
+	src/core/mainloop/mainloop_sys.c	\
 	src/core/mainloop/netstatus.c		\
 	src/core/mainloop/periodic.c		\
 	src/core/or/address_set.c		\
@@ -222,6 +223,7 @@ noinst_HEADERS +=					\
 	src/core/mainloop/cpuworker.h			\
 	src/core/mainloop/mainloop.h			\
 	src/core/mainloop/mainloop_pubsub.h		\
+	src/core/mainloop/mainloop_sys.h	        \
 	src/core/mainloop/netstatus.h			\
 	src/core/mainloop/periodic.h			\
 	src/core/or/addr_policy_st.h			\

+ 8 - 8
src/core/mainloop/mainloop.c

@@ -1550,7 +1550,7 @@ initialize_periodic_events_cb(evutil_socket_t fd, short events, void *data)
 
 /** Set up all the members of mainloop_periodic_events[], and configure them
  * all to be launched from a callback. */
-STATIC void
+void
 initialize_periodic_events(void)
 {
   if (periodic_events_initialized)
@@ -1563,7 +1563,6 @@ initialize_periodic_events(void)
   }
 
   /* Set up all periodic events. We'll launch them by roles. */
-  periodic_events_setup_all();
 
 #define NAMED_CALLBACK(name) \
   STMT_BEGIN name ## _event = periodic_events_find( #name ); STMT_END
@@ -1575,12 +1574,6 @@ initialize_periodic_events(void)
   NAMED_CALLBACK(launch_descriptor_fetches);
   NAMED_CALLBACK(check_dns_honesty);
   NAMED_CALLBACK(save_state);
-
-  struct timeval one_second = { 1, 0 };
-  initialize_periodic_events_event = tor_evtimer_new(
-                  tor_libevent_get_base(),
-                  initialize_periodic_events_cb, NULL);
-  event_add(initialize_periodic_events_event, &one_second);
 }
 
 STATIC void
@@ -2778,6 +2771,13 @@ do_main_loop(void)
    */
   initialize_periodic_events();
   initialize_mainloop_events();
+  periodic_events_setup_all();
+
+  struct timeval one_second = { 1, 0 };
+  initialize_periodic_events_event = tor_evtimer_new(
+                  tor_libevent_get_base(),
+                  initialize_periodic_events_cb, NULL);
+  event_add(initialize_periodic_events_event, &one_second);
 
 #ifdef HAVE_SYSTEMD_209
   uint64_t watchdog_delay;

+ 1 - 1
src/core/mainloop/mainloop.h

@@ -90,6 +90,7 @@ void mainloop_schedule_shutdown(int delay_sec);
 
 void tor_init_connection_lists(void);
 void initialize_mainloop_events(void);
+void initialize_periodic_events(void);
 void tor_mainloop_free_all(void);
 
 struct token_bucket_rw_t;
@@ -102,7 +103,6 @@ extern struct token_bucket_rw_t global_relayed_bucket;
 #ifdef MAINLOOP_PRIVATE
 STATIC int run_main_loop_until_done(void);
 STATIC void close_closeable_connections(void);
-STATIC void initialize_periodic_events(void);
 STATIC void teardown_periodic_events(void);
 STATIC int get_my_roles(const or_options_t *);
 STATIC int check_network_participation_callback(time_t now,

+ 32 - 0
src/core/mainloop/mainloop_sys.c

@@ -0,0 +1,32 @@
+/* Copyright (c) 2001 Matej Pfajfar.
+ * Copyright (c) 2001-2004, Roger Dingledine.
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2019, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+#include "core/or/or.h"
+#include "core/mainloop/mainloop_sys.h"
+#include "core/mainloop/mainloop.h"
+
+#include "lib/subsys/subsys.h"
+
+static int
+subsys_mainloop_initialize(void)
+{
+  initialize_periodic_events();
+  return 0;
+}
+
+static void
+subsys_mainloop_shutdown(void)
+{
+  tor_mainloop_free_all();
+}
+
+const struct subsys_fns_t sys_mainloop = {
+  .name = "mainloop",
+  .supported = true,
+  .level = 5,
+  .initialize = subsys_mainloop_initialize,
+  .shutdown = subsys_mainloop_shutdown,
+};

+ 12 - 0
src/core/mainloop/mainloop_sys.h

@@ -0,0 +1,12 @@
+/* Copyright (c) 2001 Matej Pfajfar.
+ * Copyright (c) 2001-2004, Roger Dingledine.
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2019, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+#ifndef MAINLOOP_SYS_H
+#define MAINLOOP_SYS_H
+
+extern const struct subsys_fns_t sys_mainloop;
+
+#endif

+ 3 - 0
src/test/test_periodic_event.c

@@ -51,6 +51,7 @@ test_pe_initialize(void *arg)
    * need to run the main loop and then wait for a second delaying the unit
    * tests. Instead, we'll test the callback work indepedently elsewhere. */
   initialize_periodic_events();
+  periodic_events_setup_all();
   set_network_participation(false);
   rescan_periodic_events(get_options());
 
@@ -110,6 +111,7 @@ test_pe_launch(void *arg)
 #endif
 
   initialize_periodic_events();
+  periodic_events_setup_all();
 
   /* Now that we've initialized, rescan the list to launch. */
   periodic_events_on_new_options(options);
@@ -300,6 +302,7 @@ test_pe_hs_service(void *arg)
   consider_hibernation(time(NULL));
   /* Initialize the events so we can enable them */
   initialize_periodic_events();
+  periodic_events_setup_all();
 
   /* Hack: We'll set a dumb fn() of each events so they don't get called when
    * dispatching them. We just want to test the state of the callbacks, not