[Zope3-checkins] CVS: Zope3/src/zodb - lockfile.py:1.4
Barry Warsaw
barry@wooz.org
Thu, 27 Feb 2003 18:18:35 -0500
Update of /cvs-repository/Zope3/src/zodb
In directory cvs.zope.org:/tmp/cvs-serv14535
Modified Files:
lockfile.py
Log Message:
Improve the imports so that we're not just using bare excepts. Add
support for unlock_file() so Windows has a chance of working
correctly (uses Tim's new UnlockFile() Windows function).
Implement a better API using a LockFile class, which has the semantics
wanted Berkeley storages and FileStorage.
=== Zope3/src/zodb/lockfile.py 1.3 => 1.4 ===
--- Zope3/src/zodb/lockfile.py:1.3 Wed Feb 5 18:28:34 2003
+++ Zope3/src/zodb/lockfile.py Thu Feb 27 18:18:34 2003
@@ -12,44 +12,62 @@
#
##############################################################################
-from zodb.storage.interfaces import StorageSystemError
+import os
+import errno
-# Try to create a function that creates Unix file locks.
try:
import fcntl
+except ImportError:
+ try:
+ from zodb.winlock import LockFile as _LockFile
+ from zodb.winlock import UnlockFile as _UnlockFile
+ except ImportError:
+ import logging
+ def lock_file(file):
+ logging.warn('ZODB: No file-locking support on this platform')
+
+ # Windows
+ def lock_file(file):
+ # Lock just the first byte
+ _LockFile(file.fileno(), 0, 0, 1, 0)
- lock_file_FLAG = fcntl.LOCK_EX | fcntl.LOCK_NB
+ 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")
+ 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 zodb.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")
- except:
- import logging
- def lock_file(file):
- logging.warn("FS: No file-locking support on this platform")
+ def __del__(self):
+ self.close()