Avoid parallel executions of AppManager.close()

If an AppManager.close call is started and all AppManager.services
are stopped, AppManager.run_apps starts another close() call,
resulting in a KeyError exception in close() (*1).  Prevent that using
a semaphore.

(*1) https://launchpad.net/bugs/1589746
Signed-off-by: IWAMOTO Toshihiro <iwamoto@valinux.co.jp>
Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
This commit is contained in:
IWAMOTO Toshihiro 2016-06-30 10:27:22 +09:00 committed by FUJITA Tomonori
parent d079bf38e7
commit b0ab4f1602

View File

@ -386,6 +386,7 @@ class AppManager(object):
self.applications = {}
self.contexts_cls = {}
self.contexts = {}
self.close_sem = hub.Semaphore()
def load_app(self, name):
mod = utils.import_module(name)
@ -541,7 +542,10 @@ class AppManager(object):
self._close(app)
close_dict.clear()
for app_name in list(self.applications.keys()):
self.uninstantiate(app_name)
assert not self.applications
close_all(self.contexts)
# This semaphore prevents parallel execution of this function,
# as run_apps's finally clause starts another close() call.
with self.close_sem:
for app_name in list(self.applications.keys()):
self.uninstantiate(app_name)
assert not self.applications
close_all(self.contexts)