[Zodb-checkins] CVS: ZODB3/ZODB - lock_file.py:1.8
Barry Warsaw
barry@wooz.org
Fri, 28 Feb 2003 14:50:07 -0500
Update of /cvs-repository/ZODB3/ZODB
In directory cvs.zope.org:/tmp/cvs-serv6460
Modified Files:
lock_file.py
Log Message:
Backport lock file changes from ZODB4. Specifically, implement an
unlock_file() call which awaits Tim's backport of
winlock.UnlockFile(). This is no-op on *nix.
Also, implement a better API for dealing with lock files. Use the
LockFile class for clean acquisition and release of locks, and
unlinking of lock files.
=== ZODB3/ZODB/lock_file.py 1.7 => 1.8 ===
--- ZODB3/ZODB/lock_file.py:1.7 Tue Dec 3 13:49:33 2002
+++ ZODB3/ZODB/lock_file.py Fri Feb 28 14:50:06 2003
@@ -12,47 +12,63 @@
#
##############################################################################
-from ZODB.POSException import StorageSystemError
+import os
+import errno
-# Try to create a function that creates Unix file locks.
try:
import fcntl
+except ImportError:
+ try:
+ from winlock import LockFile as _LockFile
+ from winlock import UnlockFile as _UnlockFile
+ except ImportError:
+ import zLOG
+ def lock_file(file):
+ zLOG.LOG('ZODB', zLOG.INFO,
+ 'No file-locking support on this platform')
- lock_file_FLAG = fcntl.LOCK_EX | fcntl.LOCK_NB
+ # Windows
+ def lock_file(file):
+ # Lock just the first byte
+ _LockFile(file.fileno(), 0, 0, 1, 0)
+
+ def unlock_file(file):
+ _UnlockFile(file.fileno(), 0, 0, 1, 0)
+else:
+ # Unix
+ _flags = fcntl.LOCK_EX | fcntl.LOCK_NB
def lock_file(file):
- try:
- un = file.fileno()
- except:
- return # don't care if not a real file
+ fcntl.flock(file.fileno(), _flags)
+ def unlock_file(file):
+ # File is automatically unlocked on close
+ pass
+
+
+
+# This is a better interface to use than the lockfile.lock_file() interface.
+# Creating the instance acquires the lock. The file remains open. Calling
+# close both closes and unlocks the lock file.
+class LockFile:
+ def __init__(self, path):
+ self._path = path
try:
- fcntl.flock(un, lock_file_FLAG)
- except:
- raise StorageSystemError, (
- "Could not lock the database file. There must be\n"
- "another process that has opened the file.\n"
- "<p>")
+ self._fp = open(path, 'r+')
+ except IOError, e:
+ if e.errno <> errno.ENOENT: raise
+ self._fp = open(path, 'w+')
+ # Acquire the lock and piss on the hydrant
+ lock_file(self._fp)
+ print >> self._fp, os.getpid()
+ self._fp.flush()
+
+ def close(self):
+ if self._fp is not None:
+ unlock_file(self._fp)
+ self._fp.close()
+ os.unlink(self._path)
+ self._fp = None
-except:
- # Try windows-specific code:
- try:
- from winlock import LockFile
- def lock_file(file):
- try:
- un=file.fileno()
- except:
- return # don't care if not a real file
-
- try:
- LockFile(un, 0, 0, 1, 0) # just lock the first byte, who cares
- except:
- raise StorageSystemError, (
- "Could not lock the database file. There must be\n"
- "another process that has opened the file.\n"
- "<p>")
- except:
- import zLOG
- def lock_file(file):
- zLOG.LOG("FS", zLOG.INFO,
- "No file-locking support on this platform")
+ def __del__(self):
+ self.close()