Otherwise, AppManager.run_apps fails to terminate.

Signed-off-by: IWAMOTO Toshihiro <[email protected]>
---
 ryu/base/app_manager.py                   | 7 +++++++
 ryu/controller/ofp_handler.py             | 3 ++-
 ryu/services/protocols/bgp/application.py | 9 +++++----
 ryu/services/protocols/ovsdb/manager.py   | 5 +++--
 ryu/services/protocols/vrrp/manager.py    | 5 +++--
 5 files changed, 20 insertions(+), 9 deletions(-)

diff --git a/ryu/base/app_manager.py b/ryu/base/app_manager.py
index 5b63e8c..9139820 100644
--- a/ryu/base/app_manager.py
+++ b/ryu/base/app_manager.py
@@ -156,6 +156,7 @@ class RyuApp(object):
         self.event_handlers = {}        # ev_cls -> handlers:list
         self.observers = {}     # ev_cls -> observer-name -> states:set
         self.threads = []
+        self.main_thread = None
         self.events = hub.Queue(128)
         if hasattr(self.__class__, 'LOGGER_NAME'):
             self.logger = logging.getLogger(self.__class__.LOGGER_NAME)
@@ -172,10 +173,16 @@ class RyuApp(object):
     def start(self):
         """
         Hook that is called after startup initialization is done.
+
+        A subclass can implement its own start() that return a thread.
+        In that case, the thread object must be stored in self.main_thread
+        so that the stop() method can clean up the thread.
         """
         self.threads.append(hub.spawn(self._event_loop))
 
     def stop(self):
+        if self.main_thread:
+            hub.kill(self.main_thread)
         self.is_active = False
         self._send_event(self._event_stop, None)
         hub.joinall(self.threads)
diff --git a/ryu/controller/ofp_handler.py b/ryu/controller/ofp_handler.py
index cc64b1f..d77d718 100644
--- a/ryu/controller/ofp_handler.py
+++ b/ryu/controller/ofp_handler.py
@@ -55,7 +55,8 @@ class OFPHandler(ryu.base.app_manager.RyuApp):
 
     def start(self):
         super(OFPHandler, self).start()
-        return hub.spawn(OpenFlowController())
+        self.main_thread = hub.spawn(OpenFlowController())
+        return self.main_thread
 
     def _hello_failed(self, datapath, error_desc):
         self.logger.error(error_desc)
diff --git a/ryu/services/protocols/bgp/application.py 
b/ryu/services/protocols/bgp/application.py
index 8284444..470caf6 100644
--- a/ryu/services/protocols/bgp/application.py
+++ b/ryu/services/protocols/bgp/application.py
@@ -101,14 +101,15 @@ class RyuBGPSpeaker(RyuApp):
             if getattr(settings, 'SSH', None) is not None:
                 hub.spawn(ssh.SSH_CLI_CONTROLLER.start, None, **settings.SSH)
         # Start Network Controller to server RPC peers.
-        t = hub.spawn(net_ctrl.NET_CONTROLLER.start, *[],
-                      **{net_ctrl.NC_RPC_BIND_IP: self.bind_ip,
-                      net_ctrl.NC_RPC_BIND_PORT: self.bind_port})
+        self.main_thread = hub.spawn(
+            net_ctrl.NET_CONTROLLER.start, *[],
+            **{net_ctrl.NC_RPC_BIND_IP: self.bind_ip,
+               net_ctrl.NC_RPC_BIND_PORT: self.bind_port})
         LOG.debug('Started Network Controller')
 
         super(RyuBGPSpeaker, self).start()
 
-        return t
+        return self.main_thread
 
     @classmethod
     def validate_rpc_ip(cls, ip):
diff --git a/ryu/services/protocols/ovsdb/manager.py 
b/ryu/services/protocols/ovsdb/manager.py
index 7b1d5c8..fabfca1 100644
--- a/ryu/services/protocols/ovsdb/manager.py
+++ b/ryu/services/protocols/ovsdb/manager.py
@@ -113,11 +113,12 @@ class OVSDB(app_manager.RyuApp):
 
         self.logger.info('Listening on %s:%s for clients' % (self._address,
                                                              self._port))
-        t = hub.spawn(self._accept, self._server)
+        self.main_thread = hub.spawn(self._accept, self._server)
         super(OVSDB, self).start()
-        return t
+        return self.main_thread
 
     def stop(self):
+        # TODO main_thread should be stopped first
         for client in self._clients.values():
             client.stop()
 
diff --git a/ryu/services/protocols/vrrp/manager.py 
b/ryu/services/protocols/vrrp/manager.py
index 40c730d..5cc84d4 100644
--- a/ryu/services/protocols/vrrp/manager.py
+++ b/ryu/services/protocols/vrrp/manager.py
@@ -61,11 +61,12 @@ class VRRPManager(app_manager.RyuApp):
         self.name = vrrp_event.VRRP_MANAGER_NAME
         self._instances = {}    # name -> VRRPInstance
         self.shutdown = hub.Queue()
+        self.vrrp_thread = None
 
     def start(self):
-        t = hub.spawn(self._shutdown_loop)
+        self.main_thread = hub.spawn(self._shutdown_loop)
         super(VRRPManager, self).start()
-        return t
+        return self.main_thread
 
     @handler.set_ev_cls(vrrp_event.EventVRRPConfigRequest)
     def config_request_handler(self, ev):
-- 
2.1.4


------------------------------------------------------------------------------
_______________________________________________
Ryu-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/ryu-devel

Reply via email to