From: Mike Bayer Date: Sat, 5 Mar 2011 17:19:40 +0000 (-0500) Subject: - Tightened the iterate vs. remove mutex around the X-Git-Tag: rel_0_6_7~30 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=77c8def8720db6ab2260e1e48b86d0642219e9ff;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git - Tightened the iterate vs. remove mutex around the identity map iteration, attempting to reduce the chance of an (extremely rare) reentrant gc operation causing a deadlock. Might remove the mutex in 0.7. [ticket:2087] --- diff --git a/CHANGES b/CHANGES index 54a546cf58..71243e7033 100644 --- a/CHANGES +++ b/CHANGES @@ -6,6 +6,12 @@ CHANGES 0.6.7 ===== - orm + - Tightened the iterate vs. remove mutex around the + identity map iteration, attempting to reduce the + chance of an (extremely rare) reentrant gc operation + causing a deadlock. Might remove the mutex in + 0.7. [ticket:2087] + - Added a `name` argument to `Query.subquery()`, to allow a fixed name to be assigned to the alias object. [ticket:2030] diff --git a/lib/sqlalchemy/orm/identity.py b/lib/sqlalchemy/orm/identity.py index 33f781092e..5df405fb5b 100644 --- a/lib/sqlalchemy/orm/identity.py +++ b/lib/sqlalchemy/orm/identity.py @@ -140,7 +140,9 @@ class WeakInstanceDict(IdentityMap): self._remove_mutex.acquire() try: if dict.pop(self, state.key) is not state: - raise AssertionError("State %s is not present in this identity map" % state) + raise AssertionError( + "State %s is not present in this identity map" % state + ) finally: self._remove_mutex.release() @@ -162,49 +164,46 @@ class WeakInstanceDict(IdentityMap): return default return o - - def items(self): + def _items(self): + values = self.all_states() + result = [] + for state in values: + value = state.obj() + if value is not None: + result.append((state.key, value)) + return result + + def _values(self): + values = self.all_states() + result = [] + for state in values: + value = state.obj() + if value is not None: + result.append(value) + + return result + + # Py3K + #def items(self): + # return iter(self._items()) + # + #def values(self): + # return iter(self._values()) # Py2K - return list(self.iteritems()) - + items = _items def iteritems(self): - # end Py2K - self._remove_mutex.acquire() - try: - result = [] - for state in dict.values(self): - value = state.obj() - if value is not None: - result.append((state.key, value)) - - return iter(result) - finally: - self._remove_mutex.release() - - def values(self): - # Py2K - return list(self.itervalues()) + return iter(self.items()) + values = _values def itervalues(self): + return iter(self.values()) # end Py2K - self._remove_mutex.acquire() - try: - result = [] - for state in dict.values(self): - value = state.obj() - if value is not None: - result.append(value) - - return iter(result) - finally: - self._remove_mutex.release() def all_states(self): self._remove_mutex.acquire() try: # Py3K # return list(dict.values(self)) - # Py2K return dict.values(self) # end Py2K