ZODB Components: Fix deadlock between import lock and aq_method_lock.
This only happens when using ZEO (see source code comments). Steps to reproduce: 1. Edit a ZODB Component in one tab. 2. At the same time, run Unit Tests in another tab. Backtrace: # ThreadID: 140153540167424 File: "eggs/Zope2-2.13.22-py2.7.egg/ZServer/PubCore/ZServerPublisher.py", line 31, in __init__ response=b) File: "eggs/Zope2-2.13.22-py2.7.egg/ZPublisher/Publish.py", line 455, in publish_module environ, debug, request, response) File: "eggs/Zope2-2.13.22-py2.7.egg/ZPublisher/Publish.py", line 249, in publish_module_standard response = publish(request, module_name, after_list, debug=debug) File: "parts/erp5/Products/Localizer/patches.py", line 84, in new_publish x = zope_publish(request, module_name, after_list, debug) File: "eggs/Zope2-2.13.22-py2.7.egg/ZPublisher/Publish.py", line 138, in publish request, bind=1) File: "eggs/Zope2-2.13.22-py2.7.egg/ZPublisher/mapply.py", line 44, in mapply f, count = zope.publisher.publish.unwrapMethod(object) File: "eggs/zope.publisher-3.12.6-py2.7.egg/zope/publisher/publish.py", line 46, in unwrapMethod elif getattr(unwrapped, 'func_code', None) is not None: File: "eggs/Products.ExternalMethod-2.13.0-py2.7.egg/Products/ExternalMethod/ExternalMethod.py", line 106, in <lambda> func_code = ComputedAttribute(lambda self: self.getFuncCode()) File: "eggs/Products.ExternalMethod-2.13.0-py2.7.egg/Products/ExternalMethod/ExternalMethod.py", line 190, in getFuncCode self._v_f = self.getFunction() File: "parts/erp5/Products/ERP5Type/patches/ExternalMethod.py", line 29, in getFunction level=0) File: "parts/erp5/Products/ERP5Type/dynamic/component_package.py", line 407, in load_module with aq_method_lock: File: "parts/python2.7/lib/python2.7/threading.py", line 174, in acquire rc = self.__block.acquire(blocking) => 1. Acquire Import lock in getFunction() (ZODB Component import) 2. Try to acquire aq_method_lock # ThreadID: 140153468495616 File: "eggs/Zope2-2.13.22-py2.7.egg/ZServer/PubCore/ZServerPublisher.py", line 31, in __init__ response=b) File: "eggs/Zope2-2.13.22-py2.7.egg/ZPublisher/Publish.py", line 455, in publish_module environ, debug, request, response) File: "eggs/Zope2-2.13.22-py2.7.egg/ZPublisher/Publish.py", line 249, in publish_module_standard response = publish(request, module_name, after_list, debug=debug) File: "parts/erp5/Products/Localizer/patches.py", line 84, in new_publish x = zope_publish(request, module_name, after_list, debug) File: "eggs/Zope2-2.13.22-py2.7.egg/ZPublisher/Publish.py", line 138, in publish request, bind=1) File: "eggs/Zope2-2.13.22-py2.7.egg/ZPublisher/mapply.py", line 77, in mapply if debug is not None: return debug(object,args,context) File: "eggs/Zope2-2.13.22-py2.7.egg/ZPublisher/Publish.py", line 48, in call_object result=apply(object,args) # Type s<cr> to step into published object. File: "parts/erp5/Products/TimerService/TimerService.py", line 90, in process_timer subscriptions.append(self.unrestrictedTraverse(path)) File: "eggs/Zope2-2.13.22-py2.7.egg/OFS/Traversable.py", line 249, in unrestrictedTraverse if getattr(aq_base(obj), name, _marker) is not _marker: File: "parts/erp5/Products/ERP5Type/dynamic/lazy_class.py", line 107, in __getattribute__ self.__class__.loadClass() File: "parts/erp5/Products/ERP5Type/dynamic/lazy_class.py", line 326, in loadClass class_definition = generatePortalTypeClass(site, portal_type) File: "parts/erp5/Products/ERP5Type/dynamic/portal_type_class.py", line 143, in generatePortalTypeClass type_class = portal_type.getTypeClass() File: "eggs/ZODB3-3.10.5+slapospatched001-py2.7-linux-x86_64.egg/ZODB/Connection.py", line 860, in setstate self._setstate(obj) File: "eggs/ZODB3-3.10.5+slapospatched001-py2.7-linux-x86_64.egg/ZODB/Connection.py", line 914, in _setstate self._reader.setGhostState(obj, p) File: "eggs/ZODB3-3.10.5+slapospatched001-py2.7-linux-x86_64.egg/ZODB/serialize.py", line 612, in setGhostState state = self.getState(pickle) File: "eggs/ZODB3-3.10.5+slapospatched001-py2.7-linux-x86_64.egg/ZODB/serialize.py", line 604, in getState unpickler.load() # skip the class metadata File: "eggs/ZODB3-3.10.5+slapospatched001-py2.7-linux-x86_64.egg/ZODB/serialize.py", line 474, in find_global return factory(conn, modulename, name) File: "eggs/Zope2-2.13.22-py2.7.egg/Zope2/App/ClassFactory.py", line 21, in ClassFactory m=__import__(module, _globals, _globals, _silly) => 1. Acquire aq_method_lock (generatePortalTypeClass()) 2. Try to import module and acquire Import lock
Showing
Please register or sign in to comment