[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
[tor-commits] [tor/master] Code to manage the list of subsystems.
commit 7bb76b24cf755799b7950ef078ac5ccf4d6e3a8a
Author: Nick Mathewson <nickm@xxxxxxxxxxxxxx>
Date: Thu Nov 1 11:51:33 2018 -0400
Code to manage the list of subsystems.
---
src/app/main/main.c | 6 ++
src/app/main/subsysmgr.c | 130 ++++++++++++++++++++++++++++++++++++++++++
src/app/main/subsysmgr.h | 20 +++++++
src/app/main/subsystem_list.c | 20 +++++++
src/core/include.am | 3 +
src/lib/subsys/subsys.h | 5 ++
6 files changed, 184 insertions(+)
diff --git a/src/app/main/main.c b/src/app/main/main.c
index ae87add67..444d6ea7e 100644
--- a/src/app/main/main.c
+++ b/src/app/main/main.c
@@ -15,6 +15,7 @@
#include "app/config/statefile.h"
#include "app/main/main.h"
#include "app/main/ntmain.h"
+#include "app/main/subsysmgr.h"
#include "core/mainloop/connection.h"
#include "core/mainloop/cpuworker.h"
#include "core/mainloop/mainloop.h"
@@ -813,6 +814,9 @@ tor_free_all(int postfork)
release_lockfile();
}
tor_libevent_free_all();
+
+ subsystems_shutdown();
+
/* Stuff in util.c and address.c*/
if (!postfork) {
escaped(NULL);
@@ -1426,6 +1430,8 @@ tor_run_main(const tor_main_configuration_t *tor_cfg)
event_set_mem_functions(tor_malloc_, tor_realloc_, tor_free_);
#endif
+ subsystems_init();
+
init_protocol_warning_severity_level();
update_approx_time(time(NULL));
diff --git a/src/app/main/subsysmgr.c b/src/app/main/subsysmgr.c
new file mode 100644
index 000000000..7974f2d23
--- /dev/null
+++ b/src/app/main/subsysmgr.c
@@ -0,0 +1,130 @@
+/* Copyright (c) 2003-2004, Roger Dingledine
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2018, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+#include "orconfig.h"
+#include "app/main/subsysmgr.h"
+#include "lib/err/torerr.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+/**
+ * True iff we have checked tor_subsystems for consistency.
+ **/
+static bool subsystem_array_validated = false;
+
+/**
+ * True if a given subsystem is initialized. Expand this array if there
+ * are more than this number of subsystems. (We'd rather not
+ * dynamically allocate in this module.)
+ **/
+static bool sys_initialized[128];
+
+/**
+ * Exit with a raw assertion if the subsystems list is inconsistent;
+ * initialize the subsystem_initialized array.
+ **/
+static void
+check_and_setup(void)
+{
+ if (subsystem_array_validated)
+ return;
+
+ raw_assert(ARRAY_LENGTH(sys_initialized) >= n_tor_subsystems);
+ memset(sys_initialized, 0, sizeof(sys_initialized));
+
+ int last_level = MIN_SUBSYS_LEVEL;
+
+ for (unsigned i = 0; i < n_tor_subsystems; ++i) {
+ const subsys_fns_t *sys = tor_subsystems[i];
+ if (sys->level < MIN_SUBSYS_LEVEL || sys->level > MAX_SUBSYS_LEVEL) {
+ fprintf(stderr, "BUG: Subsystem %s (at %u) has an invalid level %d. "
+ "It is supposed to be between %d and %d (inclusive).\n",
+ sys->name, i, sys->level, MIN_SUBSYS_LEVEL, MAX_SUBSYS_LEVEL);
+ raw_assert_unreached_msg("There is a bug in subsystem_list.c");
+ }
+ if (sys->level < last_level) {
+ fprintf(stderr, "BUG: Subsystem %s (at #%u) is in the wrong position. "
+ "Its level is %d; but the previous subsystem's level was %d.\n",
+ sys->name, i, sys->level, last_level);
+ raw_assert_unreached_msg("There is a bug in subsystem_list.c");
+ }
+ last_level = sys->level;
+ }
+
+ subsystem_array_validated = true;
+}
+
+/**
+ * Initialize all the subsystems; exit on failure.
+ **/
+int
+subsystems_init(void)
+{
+ return subsystems_init_upto(MAX_SUBSYS_LEVEL);
+}
+
+/**
+ * Initialize all the subsystems whose level is less than or equal to
+ * <b>target_level</b>; exit on failure.
+ **/
+int
+subsystems_init_upto(int target_level)
+{
+ check_and_setup();
+
+ for (unsigned i = 0; i < n_tor_subsystems; ++i) {
+ const subsys_fns_t *sys = tor_subsystems[i];
+ if (!sys->supported)
+ continue;
+ if (sys->level > target_level)
+ break;
+ if (sys_initialized[i])
+ continue;
+ int r = 0;
+ if (sys->initialize)
+ r = sys->initialize();
+ if (r < 0) {
+ fprintf(stderr, "BUG: subsystem %s (at %u) initialization failed.\n",
+ sys->name, i);
+ raw_assert_unreached_msg("A subsystem couldn't be initialized.");
+ }
+ sys_initialized[i] = true;
+ }
+
+ return 0;
+}
+
+/**
+ * Shut down all the subsystems.
+ **/
+void
+subsystems_shutdown(void)
+{
+ subsystems_shutdown_downto(MIN_SUBSYS_LEVEL - 1);
+}
+
+/**
+ * Shut down all the subsystems whose level is above <b>target_level</b>.
+ **/
+void
+subsystems_shutdown_downto(int target_level)
+{
+ check_and_setup();
+
+ for (int i = (int)n_tor_subsystems - 1; i >= 0; --i) {
+ const subsys_fns_t *sys = tor_subsystems[i];
+ if (!sys->supported)
+ continue;
+ if (sys->level <= target_level)
+ break;
+ if (! sys_initialized[i])
+ continue;
+ if (sys->shutdown)
+ sys->shutdown();
+ sys_initialized[i] = false;
+ }
+}
diff --git a/src/app/main/subsysmgr.h b/src/app/main/subsysmgr.h
new file mode 100644
index 000000000..c9b892eee
--- /dev/null
+++ b/src/app/main/subsysmgr.h
@@ -0,0 +1,20 @@
+/* Copyright (c) 2003-2004, Roger Dingledine
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2018, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+#ifndef TOR_SUBSYSMGR_T
+#define TOR_SUBSYSMGR_T
+
+#include "lib/subsys/subsys.h"
+
+extern const struct subsys_fns_t *tor_subsystems[];
+extern const unsigned n_tor_subsystems;
+
+int subsystems_init(void);
+int subsystems_init_upto(int level);
+
+void subsystems_shutdown(void);
+void subsystems_shutdown_downto(int level);
+
+#endif
diff --git a/src/app/main/subsystem_list.c b/src/app/main/subsystem_list.c
new file mode 100644
index 000000000..fc1249e1c
--- /dev/null
+++ b/src/app/main/subsystem_list.c
@@ -0,0 +1,20 @@
+/* Copyright (c) 2003-2004, Roger Dingledine
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2018, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+#include "orconfig.h"
+#include "app/main/subsysmgr.h"
+#include "lib/cc/compat_compiler.h"
+#include "lib/cc/torint.h"
+
+#include <stddef.h>
+
+/**
+ * Global list of the subsystems in Tor, in the order of their initialization.
+ **/
+const subsys_fns_t *tor_subsystems[] = {
+ NULL // placeholder.
+};
+
+const unsigned n_tor_subsystems = ARRAY_LENGTH(tor_subsystems);
diff --git a/src/core/include.am b/src/core/include.am
index 1b8ef2ac5..d3fce5428 100644
--- a/src/core/include.am
+++ b/src/core/include.am
@@ -11,6 +11,8 @@ LIBTOR_APP_A_SOURCES = \
src/app/config/confparse.c \
src/app/config/statefile.c \
src/app/main/main.c \
+ src/app/main/subsystem_list.c \
+ src/app/main/subsysmgr.c \
src/core/crypto/hs_ntor.c \
src/core/crypto/onion_crypto.c \
src/core/crypto/onion_fast.c \
@@ -191,6 +193,7 @@ noinst_HEADERS += \
src/app/config/statefile.h \
src/app/main/main.h \
src/app/main/ntmain.h \
+ src/app/main/subsysmgr.h \
src/core/crypto/hs_ntor.h \
src/core/crypto/onion_crypto.h \
src/core/crypto/onion_fast.h \
diff --git a/src/lib/subsys/subsys.h b/src/lib/subsys/subsys.h
index 7e4fe5363..012b218da 100644
--- a/src/lib/subsys/subsys.h
+++ b/src/lib/subsys/subsys.h
@@ -43,6 +43,8 @@ typedef struct subsys_fns_t {
*
* This function MUST NOT rely on any runtime configuration information;
* it is only for global state or pre-configuration state.
+ *
+ * This function MUST NOT have any parts that can fail.
**/
int (*initialize)(void);
@@ -60,4 +62,7 @@ typedef struct subsys_fns_t {
} subsys_fns_t;
+#define MIN_SUBSYS_LEVEL -100
+#define MAX_SUBSYS_LEVEL 100
+
#endif
_______________________________________________
tor-commits mailing list
tor-commits@xxxxxxxxxxxxxxxxxxxx
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits