[PATCH 2 of 2] transaction: clear callback instances after usage
Gregory Szorc
gregory.szorc at gmail.com
Sat Apr 16 12:08:40 EDT 2016
# HG changeset patch
# User Gregory Szorc <gregory.szorc at gmail.com>
# Date 1460822557 25200
# Sat Apr 16 09:02:37 2016 -0700
# Node ID a6425e909cd3bdee41aea6aeed682298c2bc8073
# Parent 9acb28de651539bfb776eba9e2a59bc8cb3a52f0
transaction: clear callback instances after usage
Prevents double usage and helps reduce reference cycles, which
were observed to occur in `hg convert` and other scenarios where
there are multiple transactions per process.
diff --git a/mercurial/transaction.py b/mercurial/transaction.py
--- a/mercurial/transaction.py
+++ b/mercurial/transaction.py
@@ -426,16 +426,18 @@ class transaction(object):
def close(self):
'''commit the transaction'''
if self.count == 1:
self.validator(self) # will raise exception if needed
self._generatefiles(group=GenerationGroup.PREFINALIZE)
categories = sorted(self._finalizecallback)
for cat in categories:
self._finalizecallback[cat](self)
+ # Prevent double usage and help clear cycles.
+ self._finalizecallback = None
self._generatefiles(group=GenerationGroup.POSTFINALIZE)
self.count -= 1
if self.count != 0:
return
self.file.close()
self._backupsfile.close()
# cleanup temporary files
@@ -481,16 +483,18 @@ class transaction(object):
self.journal = None
self.releasefn(self, True) # notify success of closing transaction
# run post close action
categories = sorted(self._postclosecallback)
for cat in categories:
self._postclosecallback[cat](self)
+ # Prevent double usage and help clear cycles.
+ self._postclosecallback = None
@active
def abort(self):
'''abort the transaction (generally called on error, or when the
transaction is not explicitly committed before going out of
scope)'''
self._abort()
@@ -534,16 +538,18 @@ class transaction(object):
self.opener.unlink(self.journal)
return
self.report(_("transaction abort!\n"))
try:
for cat in sorted(self._abortcallback):
self._abortcallback[cat](self)
+ # Prevent double usage and help clear cycles.
+ self._abortcallback = None
_playback(self.journal, self.report, self.opener, self._vfsmap,
self.entries, self._backupentries, False)
self.report(_("rollback completed\n"))
except BaseException:
self.report(_("rollback failed - please run hg recover\n"))
finally:
self.journal = None
self.releasefn(self, False) # notify failure of transaction
More information about the Mercurial-devel
mailing list