subsysmgr.c 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. /* Copyright (c) 2003-2004, Roger Dingledine
  2. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
  3. * Copyright (c) 2007-2018, The Tor Project, Inc. */
  4. /* See LICENSE for licensing information */
  5. #include "orconfig.h"
  6. #include "app/main/subsysmgr.h"
  7. #include "lib/err/torerr.h"
  8. #include <stdio.h>
  9. #include <stdlib.h>
  10. #include <string.h>
  11. /**
  12. * True iff we have checked tor_subsystems for consistency.
  13. **/
  14. static bool subsystem_array_validated = false;
  15. /**
  16. * True if a given subsystem is initialized. Expand this array if there
  17. * are more than this number of subsystems. (We'd rather not
  18. * dynamically allocate in this module.)
  19. **/
  20. static bool sys_initialized[128];
  21. /**
  22. * Exit with a raw assertion if the subsystems list is inconsistent;
  23. * initialize the subsystem_initialized array.
  24. **/
  25. static void
  26. check_and_setup(void)
  27. {
  28. if (subsystem_array_validated)
  29. return;
  30. raw_assert(ARRAY_LENGTH(sys_initialized) >= n_tor_subsystems);
  31. memset(sys_initialized, 0, sizeof(sys_initialized));
  32. int last_level = MIN_SUBSYS_LEVEL;
  33. for (unsigned i = 0; i < n_tor_subsystems; ++i) {
  34. const subsys_fns_t *sys = tor_subsystems[i];
  35. if (sys->level < MIN_SUBSYS_LEVEL || sys->level > MAX_SUBSYS_LEVEL) {
  36. fprintf(stderr, "BUG: Subsystem %s (at %u) has an invalid level %d. "
  37. "It is supposed to be between %d and %d (inclusive).\n",
  38. sys->name, i, sys->level, MIN_SUBSYS_LEVEL, MAX_SUBSYS_LEVEL);
  39. raw_assert_unreached_msg("There is a bug in subsystem_list.c");
  40. }
  41. if (sys->level < last_level) {
  42. fprintf(stderr, "BUG: Subsystem %s (at #%u) is in the wrong position. "
  43. "Its level is %d; but the previous subsystem's level was %d.\n",
  44. sys->name, i, sys->level, last_level);
  45. raw_assert_unreached_msg("There is a bug in subsystem_list.c");
  46. }
  47. last_level = sys->level;
  48. }
  49. subsystem_array_validated = true;
  50. }
  51. /**
  52. * Initialize all the subsystems; exit on failure.
  53. **/
  54. int
  55. subsystems_init(void)
  56. {
  57. return subsystems_init_upto(MAX_SUBSYS_LEVEL);
  58. }
  59. /**
  60. * Initialize all the subsystems whose level is less than or equal to
  61. * <b>target_level</b>; exit on failure.
  62. **/
  63. int
  64. subsystems_init_upto(int target_level)
  65. {
  66. check_and_setup();
  67. for (unsigned i = 0; i < n_tor_subsystems; ++i) {
  68. const subsys_fns_t *sys = tor_subsystems[i];
  69. if (!sys->supported)
  70. continue;
  71. if (sys->level > target_level)
  72. break;
  73. if (sys_initialized[i])
  74. continue;
  75. int r = 0;
  76. if (sys->initialize)
  77. r = sys->initialize();
  78. if (r < 0) {
  79. fprintf(stderr, "BUG: subsystem %s (at %u) initialization failed.\n",
  80. sys->name, i);
  81. raw_assert_unreached_msg("A subsystem couldn't be initialized.");
  82. }
  83. sys_initialized[i] = true;
  84. }
  85. return 0;
  86. }
  87. /**
  88. * Shut down all the subsystems.
  89. **/
  90. void
  91. subsystems_shutdown(void)
  92. {
  93. subsystems_shutdown_downto(MIN_SUBSYS_LEVEL - 1);
  94. }
  95. /**
  96. * Shut down all the subsystems whose level is above <b>target_level</b>.
  97. **/
  98. void
  99. subsystems_shutdown_downto(int target_level)
  100. {
  101. check_and_setup();
  102. for (int i = (int)n_tor_subsystems - 1; i >= 0; --i) {
  103. const subsys_fns_t *sys = tor_subsystems[i];
  104. if (!sys->supported)
  105. continue;
  106. if (sys->level <= target_level)
  107. break;
  108. if (! sys_initialized[i])
  109. continue;
  110. if (sys->shutdown)
  111. sys->shutdown();
  112. sys_initialized[i] = false;
  113. }
  114. }