[PATCH 2 of 6] transaction: ensure finished transactions are not reused

Henrik Stuart hg at hstuart.dk
Wed Apr 22 02:58:44 CDT 2009


# HG changeset patch
# User Henrik Stuart <hg at hstuart.dk>
# Date 1240219102 -7200
# Node ID 2151199c0ee8b815dc83ec410a3721d0a60cbe04
# Parent  610cefac85c02e9053fb0ba66cc0fb607357dced
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 <cryo at cyanite.org>

diff -r 610cefac85c0 -r 2151199c0ee8 mercurial/transaction.py
--- a/mercurial/transaction.py	Wed Apr 22 08:54:36 2009 +0200
+++ b/mercurial/transaction.py	Mon Apr 20 11:18:22 2009 +0200
@@ -13,6 +13,16 @@
 
 from i18n import _
 import os, errno
+import error
+
+def active(func):
+    def _active(*args, **kwds):
+        self = args[0]
+        if self.count == 0:
+            raise error.Abort(_(
+                'cannot use transaction when it is already committed/aborted'))
+        return func(*args, **kwds)
+    return _active
 
 class transaction(object):
     def __init__(self, report, opener, journal, after=None, createmode=None):
@@ -32,15 +42,17 @@
 
     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))
         self.map[file] = len(self.entries) - 1
         self._write("%s\0%d\n" % (file, offset))
 
+    @active
     def flush(self):
         os.fsync(self.file.fileno())
 
@@ -49,11 +61,13 @@
         self.file.write(data)
         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)
@@ -61,6 +75,7 @@
         self.entries[index] = (file, offset, data)
         self._write("%s\0%d\n" % (file, offset))
 
+    @active
     def nest(self):
         self.count += 1
         return self
@@ -68,6 +83,7 @@
     def running(self):
         return self.count > 0
 
+    @active
     def close(self):
         self.count -= 1
         if self.count != 0:
@@ -80,7 +96,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"))


More information about the Mercurial-devel mailing list