From 16ff4960ac3b3118a9b96e21dc11a64bb7c36e21 Mon Sep 17 00:00:00 2001 From: Zac Medico Date: Sun, 22 Feb 2009 06:00:34 +0000 Subject: [PATCH] Use a lock to ensure that threaded code doesn't cause problems with proxy registration and unregistration. svn path=/main/trunk/; revision=12683 --- pym/portage/proxy/lazyimport.py | 51 +++++++++++++++++++++++---------- 1 file changed, 36 insertions(+), 15 deletions(-) diff --git a/pym/portage/proxy/lazyimport.py b/pym/portage/proxy/lazyimport.py index 954b29d74..1a4a246ef 100644 --- a/pym/portage/proxy/lazyimport.py +++ b/pym/portage/proxy/lazyimport.py @@ -6,16 +6,27 @@ __all__ = ['lazyimport'] import sys import types + +try: + import threading +except ImportError: + import dummy_threading as threading + from portage.proxy.objectproxy import ObjectProxy _module_proxies = {} +_module_proxies_lock = threading.RLock() def _register_module_proxy(name, proxy): - proxy_list = _module_proxies.get(name) - if proxy_list is None: - proxy_list = [] - _module_proxies[name] = proxy_list - proxy_list.append(proxy) + _module_proxies_lock.acquire() + try: + proxy_list = _module_proxies.get(name) + if proxy_list is None: + proxy_list = [] + _module_proxies[name] = proxy_list + proxy_list.append(proxy) + finally: + _module_proxies_lock.release() def _unregister_module_proxy(name): """ @@ -24,20 +35,30 @@ def _unregister_module_proxy(name): destroy those proxies too. This way, destruction of a single proxy can trigger destruction of all the rest. """ - proxy_list = _module_proxies.get(name) - if proxy_list is not None: - del _module_proxies[name] - for proxy in proxy_list: - object.__getattribute__(proxy, '_get_target')() - - modules = sys.modules - for name, proxy_list in list(_module_proxies.iteritems()): - if name not in modules: - continue + _module_proxies_lock.acquire() + try: + proxy_list = _module_proxies.get(name) + if proxy_list is not None: + # First delete this name from the dict so that + # if this same thread reenters below, it won't + # enter this path again. del _module_proxies[name] for proxy in proxy_list: object.__getattribute__(proxy, '_get_target')() + modules = sys.modules + for name, proxy_list in list(_module_proxies.iteritems()): + if name not in modules: + continue + # First delete this name from the dict so that + # if this same thread reenters below, it won't + # enter this path again. + del _module_proxies[name] + for proxy in proxy_list: + object.__getattribute__(proxy, '_get_target')() + finally: + _module_proxies_lock.release() + class _LazyImport(ObjectProxy): __slots__ = ('_scope', '_alias', '_name', '_target') -- 2.26.2