[tor-commits] [arm/master] Simplifying the starter's _shutdown_daemons()

atagar at torproject.org atagar at torproject.org
Fri Dec 20 18:33:04 UTC 2013


commit ba854713cb325789b33f92973e1c9861fca40511
Author: Damian Johnson <atagar at torproject.org>
Date:   Fri Dec 20 10:29:59 2013 -0800

    Simplifying the starter's _shutdown_daemons()
    
    When halting daemons we always follow the same pattern:
    
      * call stop() on every thread
      * call join() on every thread
    
    Having the modules that run daemons (the Controller and trackers) provide stop
    funcions that halt all their constituent daemons, providing back a thread that
    does so. This in turn allows our starter to be a lot cleaner.
---
 arm/controller.py   |   19 +++++++++++++++++++
 arm/starter.py      |   41 ++++++++++-------------------------------
 arm/util/tracker.py |   26 ++++++++++++++++++++++++++
 3 files changed, 55 insertions(+), 31 deletions(-)

diff --git a/arm/controller.py b/arm/controller.py
index a68fe41..9cef92e 100644
--- a/arm/controller.py
+++ b/arm/controller.py
@@ -64,6 +64,25 @@ def getController():
 
   return ARM_CONTROLLER
 
+def stop_controller():
+  """
+  Halts our Controller, providing back the thread doing so.
+  """
+
+  def halt_controller():
+    control = getController()
+
+    if control:
+      for panel_impl in control.getDaemonPanels():
+        panel_impl.stop()
+
+      for panel_impl in control.getDaemonPanels():
+        panel_impl.join()
+
+  halt_thread = threading.Thread(target = halt_controller)
+  halt_thread.start()
+  return halt_thread
+
 def initController(stdscr, startTime):
   """
   Spawns the controller, and related panels for it.
diff --git a/arm/starter.py b/arm/starter.py
index 19292a8..e497c72 100644
--- a/arm/starter.py
+++ b/arm/starter.py
@@ -14,12 +14,12 @@ import os
 import platform
 import sys
 import time
+import threading
 
 import arm
 import arm.controller
 import arm.logPanel
 import arm.util.panel
-import arm.util.sysTools
 import arm.util.torConfig
 import arm.util.torTools
 import arm.util.tracker
@@ -269,38 +269,17 @@ def _shutdown_daemons():
   Stops and joins on worker threads.
   """
 
-  # stops panel daemons
+  halt_tor_controller = threading.Thread(target = arm.util.torTools.getConn().close)
+  halt_tor_controller.start()
 
-  control = arm.controller.getController()
+  halt_threads = [
+    arm.controller.stop_controller(),
+    arm.util.tracker.stop_trackers(),
+    halt_tor_controller,
+  ]
 
-  if control:
-    for panel_impl in control.getDaemonPanels():
-      panel_impl.stop()
-
-    for panel_impl in control.getDaemonPanels():
-      panel_impl.join()
-
-  # joins on stem threads
-
-  arm.util.torTools.getConn().close()
-
-  # joins on utility daemon threads - this might take a moment since the
-  # internal threadpools being joined might be sleeping
-
-  resource_tracker = arm.util.tracker.get_resource_tracker() if arm.util.tracker.get_resource_tracker().is_alive() else None
-  connection_resolver = arm.util.tracker.get_connection_tracker() if arm.util.tracker.get_connection_tracker().is_alive() else None
-
-  if resource_tracker:
-    resource_tracker.stop()
-
-  if connection_resolver:
-    connection_resolver.stop()  # sets halt flag (returning immediately)
-
-  if resource_tracker:
-    resource_tracker.join()
-
-  if connection_resolver:
-    connection_resolver.join()  # joins on halted resolver
+  for thread in halt_threads:
+    thread.join()
 
 
 def main():
diff --git a/arm/util/tracker.py b/arm/util/tracker.py
index 0304a6c..ee4fdcc 100644
--- a/arm/util/tracker.py
+++ b/arm/util/tracker.py
@@ -6,6 +6,8 @@ Background tasks for gathering informatino about the tor process.
   get_connection_tracker - provides a ConnectionTracker for our tor process
   get_resource_tracker - provides a ResourceTracker for our tor process
 
+  stop_trackers - halts any active trackers
+
   Daemon - common parent for resolvers
     |- run_counter - number of successful runs
     |- get_rate - provides the rate at which we run
@@ -90,6 +92,30 @@ def get_resource_tracker():
   return RESOURCE_TRACKER
 
 
+def stop_trackers():
+  """
+  Halts active trackers, providing back the thread shutting them down.
+
+  :returns: **threading.Thread** shutting down the daemons
+  """
+
+  def halt_trackers():
+    trackers = filter(lambda t: t.is_alive(), [
+      get_resource_tracker(),
+      get_connection_tracker(),
+    ])
+
+    for tracker in trackers:
+      tracker.stop()
+
+    for tracker in trackers:
+      tracker.join()
+
+  halt_thread = threading.Thread(target = halt_trackers)
+  halt_thread.start()
+  return halt_thread
+
+
 def _resources_via_ps(pid):
   """
   Fetches resource usage information about a given process via ps. This returns



More information about the tor-commits mailing list