Commit 9e783585 authored by Arnaud Fontaine's avatar Arnaud Fontaine

Use aq_method_lock rather than defining separate locks for ZODB Components.

Before, there was a separate lock for generating the registry and loading a
Component which was wrong as the latter use the registry. Also, as reset was
using aq_method_lock, modules could be reset while being loaded at the same
time.
parent 2fb1b3f1
......@@ -34,6 +34,7 @@ import sys
import threading
from Products.ERP5.ERP5Site import getSite
from Products.ERP5Type.Base import Base
from types import ModuleType
from zLOG import LOG, INFO, BLATHER
......@@ -72,8 +73,6 @@ class ComponentDynamicPackage(ModuleType):
self._namespace_prefix = namespace + '.'
self._portal_type = portal_type
self.__version_suffix_len = len('_version')
self._load_module_lock = threading.RLock()
self._registry_generate_lock = threading.RLock()
self.__registry_dict = {}
# Add this module to sys.path for future imports
......@@ -110,7 +109,7 @@ class ComponentDynamicPackage(ModuleType):
# this is only done at startup or upon reset, moreover using the Catalog
# is too risky as it lags behind and depends upon objects being
# reindexed
with self._registry_generate_lock:
with Base.aq_method_lock:
for component in component_tool.objectValues(portal_type=self._portal_type):
# Only consider modified or validated states as state transition will
# be handled by component_validation_workflow which will take care of
......@@ -184,7 +183,7 @@ class ComponentDynamicPackage(ModuleType):
return version_package
def load_module(self, fullname):
def __load_module(self, fullname):
"""
Load a module with given fullname (see PEP 302) if it's not
already in sys.modules. It is assumed that imports are filtered
......@@ -233,16 +232,12 @@ class ComponentDynamicPackage(ModuleType):
except AttributeError:
pass
else:
with self._load_module_lock:
setattr(self._getVersionPackage(version), name, module)
return module
module_fullname_alias = self._namespace + '.' + name
module_fullname = '%s.%s_version.%s' % (self._namespace, version, name)
with self._load_module_lock:
module = ModuleType(module_fullname, component.getDescription())
# The module *must* be in sys.modules before executing the code in case
......@@ -275,6 +270,14 @@ class ComponentDynamicPackage(ModuleType):
return module
def load_module(self, fullname):
"""
Make sure that loading module is thread-safe using aq_method_lock to make
sure that modules do not disappear because of an ongoing reset
"""
with Base.aq_method_lock:
return self.__load_module(fullname)
def reset(self, sub_package=None):
"""
Reset the content of the current package and its version package as well
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment