[Checkins] SVN: zope.interface/branches/jinty-mem/src/zope/interface/interface.py Fix threading issue in Specification.subscribe brought up by Laurence Rowe. Document that there is a threading issue in setTaggedValue, but we should be safe ignoring it (thanks Tres).

Brian Sutherland jinty at web.de
Thu Nov 11 03:44:15 EST 2010


Log message for revision 118339:
  Fix threading issue in Specification.subscribe brought up by Laurence Rowe. Document that there is a threading issue in setTaggedValue, but we should be safe ignoring it (thanks Tres).

Changed:
  U   zope.interface/branches/jinty-mem/src/zope/interface/interface.py

-=-
Modified: zope.interface/branches/jinty-mem/src/zope/interface/interface.py
===================================================================
--- zope.interface/branches/jinty-mem/src/zope/interface/interface.py	2010-11-11 08:29:35 UTC (rev 118338)
+++ zope.interface/branches/jinty-mem/src/zope/interface/interface.py	2010-11-11 08:44:15 UTC (rev 118339)
@@ -97,6 +97,11 @@
         """ Associates 'value' with 'key'. """
         tv = self.__tagged_values
         if tv is None:
+            # there is a threading issue here, but we should be safe neglecting
+            # it because: "no sane code will call 'setTaggedValue' except at
+            # import time, when we should be serialized by Python's own import
+            # lock."
+            # https://mail.zope.org/pipermail/zope-dev/2010-November/041983.html
             self.__tagged_values = tv = {}
         tv[tag] = value
 
@@ -278,9 +283,11 @@
         self.__bases__ = tuple(bases)
 
     def subscribe(self, dependent):
-        if self.dependents is None:
-            self.dependents = weakref.WeakKeyDictionary()
-        self.dependents[dependent] = self.dependents.get(dependent, 0) + 1
+        dependents = self.dependents
+        if dependents is None:
+            # use of setdefault avoids threading issues
+            dependents = self.__dict__.setdefault('dependents', weakref.WeakKeyDictionary())
+        dependents[dependent] = dependents.get(dependent, 0) + 1
 
     def unsubscribe(self, dependent):
         if self.dependents is None:



More information about the checkins mailing list