# HG changeset patch # User Henrik Stuart # Date 1240559813 -7200 # Node ID fe8a3e56039ff8922a8455eea3390e47b9501276 # Parent 9de088320e9ac943e491beb9017b3673002b95b9 transaction: ensure finished transactions are not reused All transactional methods on the transaction class have had a decorator added that ensures the transaction is running. Co-contributor: Sune Foldager diff -r 9de088320e9a -r fe8a3e56039f mercurial/transaction.py --- a/mercurial/transaction.py Mon May 04 03:49:57 2009 +0200 +++ b/mercurial/transaction.py Fri Apr 24 09:56:53 2009 +0200 @@ -13,6 +13,15 @@ from i18n import _ import os, errno +import error + +def active(func): + def _active(self, *args, **kwds): + if self.count == 0: + raise error.Abort(_( + 'cannot use transaction when it is already committed/aborted')) + return func(self, *args, **kwds) + return _active class transaction(object): def __init__(self, report, opener, journal, after=None, createmode=None): @@ -32,9 +41,10 @@ def __del__(self): if self.journal: - if self.entries: self.abort() + if self.entries: self._abort() self.file.close() + @active def add(self, file, offset, data=None): if file in self.map: return self.entries.append((file, offset, data)) @@ -43,11 +53,13 @@ self.file.write("%s\0%d\n" % (file, offset)) self.file.flush() + @active def find(self, file): if file in self.map: return self.entries[self.map[file]] return None + @active def replace(self, file, offset, data=None): if file not in self.map: raise KeyError(file) @@ -56,6 +68,7 @@ self.file.write("%s\0%d\n" % (file, offset)) self.file.flush() + @active def nest(self): self.count += 1 return self @@ -63,6 +76,7 @@ def running(self): return self.count > 0 + @active def close(self): self.count -= 1 if self.count != 0: @@ -75,7 +89,11 @@ os.unlink(self.journal) self.journal = None + @active def abort(self): + self._abort() + + def _abort(self): if not self.entries: return self.report(_("transaction abort!\n"))