From: Mike Bayer Date: Sun, 18 Nov 2007 17:31:09 +0000 (+0000) Subject: - added a little more checking for garbage-collection dereferences in X-Git-Tag: rel_0_4_1~8 X-Git-Url: http://git.ipfire.org/gitweb/gitweb.cgi?a=commitdiff_plain;h=08a434881faa14eab8f17274b97af042903eaba9;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git - added a little more checking for garbage-collection dereferences in InstanceState.__cleanup() to reduce "gc ignored" errors on app shutdown --- diff --git a/CHANGES b/CHANGES index 0018b83893..653d58a22f 100644 --- a/CHANGES +++ b/CHANGES @@ -107,7 +107,11 @@ CHANGES - fixed error where Query.add_column() would not accept a class-bound attribute as an argument; Query also raises an error if an invalid argument was sent to add_column() (at instances() time) [ticket:858] - + + - added a little more checking for garbage-collection dereferences in + InstanceState.__cleanup() to reduce "gc ignored" errors on app + shutdown + - The session API has been solidified: - It's an error to session.save() an object which is already diff --git a/lib/sqlalchemy/orm/attributes.py b/lib/sqlalchemy/orm/attributes.py index 6cf2b74e97..27f4b017c3 100644 --- a/lib/sqlalchemy/orm/attributes.py +++ b/lib/sqlalchemy/orm/attributes.py @@ -557,19 +557,25 @@ class InstanceState(object): self.instance_dict = None def __cleanup(self, ref): - if self.instance_dict is None or self.instance_dict() is None: + # tiptoe around Python GC unpredictableness + instance_dict = self.instance_dict + if instance_dict is None: return - instance_dict = self.instance_dict() - + instance_dict = instance_dict() + if instance_dict is None: + return + # the mutexing here is based on the assumption that gc.collect() # may be firing off cleanup handlers in a different thread than that # which is normally operating upon the instance dict. instance_dict._mutex.acquire() try: # if instance_dict de-refed us, or it called our - # _resurrect, return - if self.instance_dict is None or self.instance_dict() is None or self.obj() is not None: + # _resurrect, return. again setting local copy + # to avoid the rug being pulled in between + id2 = self.instance_dict + if id2 is None or id2() is None or self.obj() is not None: return self.__resurrect(instance_dict)