summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: a5ccc96)
raw | patch | inline | side by side (parent: a5ccc96)
author | richard <richard@57a73879-2fb5-44c3-a270-3262357dd7e2> | |
Sun, 19 Jan 2003 23:14:42 +0000 (23:14 +0000) | ||
committer | richard <richard@57a73879-2fb5-44c3-a270-3262357dd7e2> | |
Sun, 19 Jan 2003 23:14:42 +0000 (23:14 +0000) |
git-svn-id: http://svn.roundup-tracker.org/svnroot/roundup/trunk@1464 57a73879-2fb5-44c3-a270-3262357dd7e2
roundup/backends/portalocker.py | patch | blob | history |
index fc0005bf344235b0ce0550e31314ba9ac3450d1c..219ae24043536e054235b5af37bc0c708e2a760e 100644 (file)
# Requires python 1.5.2 or better.
# ID line added by richard for Roundup file tracking
-# $Id: portalocker.py,v 1.2 2002-10-03 06:56:29 richard Exp $
+# $Id: portalocker.py,v 1.3 2003-01-19 23:14:42 richard Exp $
""" Cross-platform (posix/nt) API for flock-style file locking.
import os
if os.name == 'nt':
- import win32con
- import win32file
- import pywintypes
- LOCK_EX = win32con.LOCKFILE_EXCLUSIVE_LOCK
- LOCK_SH = 0 # the default
- LOCK_NB = win32con.LOCKFILE_FAIL_IMMEDIATELY
- # is there any reason not to reuse the following structure?
- __overlapped = pywintypes.OVERLAPPED()
+ import win32con
+ import win32file
+ import pywintypes
+ LOCK_EX = win32con.LOCKFILE_EXCLUSIVE_LOCK
+ LOCK_SH = 0 # the default
+ LOCK_NB = win32con.LOCKFILE_FAIL_IMMEDIATELY
+ # is there any reason not to reuse the following structure?
+ __overlapped = pywintypes.OVERLAPPED()
elif os.name == 'posix':
- import fcntl
- LOCK_EX = fcntl.LOCK_EX
- LOCK_SH = fcntl.LOCK_SH
- LOCK_NB = fcntl.LOCK_NB
+ import fcntl
+ LOCK_EX = fcntl.LOCK_EX
+ LOCK_SH = fcntl.LOCK_SH
+ LOCK_NB = fcntl.LOCK_NB
else:
- raise RuntimeError("PortaLocker only defined for nt and posix platforms")
+ raise RuntimeError("PortaLocker only defined for nt and posix platforms")
if os.name == 'nt':
- def lock(file, flags):
- hfile = win32file._get_osfhandle(file.fileno())
- win32file.LockFileEx(hfile, flags, 0, 0xffff0000, __overlapped)
-
- def unlock(file):
- hfile = win32file._get_osfhandle(file.fileno())
- win32file.UnlockFileEx(hfile, 0, 0xffff0000, __overlapped)
+ def lock(file, flags):
+ hfile = win32file._get_osfhandle(file.fileno())
+ # LockFileEx is not supported on all Win32 platforms (Win95, Win98, WinME).
+ # If it's not supported, win32file will raise an exception.
+ # Try LockFileEx first, as it has more functionality and handles
+ # blocking locks more efficiently.
+ try:
+ win32file.LockFileEx(hfile, flags, 0, 0xffff0000, __overlapped)
+ except win32file.error, e:
+ import winerror
+ # Propagate upwards all exceptions other than not-implemented.
+ if e[0] != winerror.ERROR_CALL_NOT_IMPLEMENTED:
+ raise e
+
+ # LockFileEx is not supported. Use LockFile.
+ # LockFile does not support shared locking -- always exclusive.
+ # Care: the low/high length params are reversed compared to LockFileEx.
+ if not flags & LOCK_EX:
+ import warnings
+ warnings.warn("PortaLocker does not support shared locking on Win9x", RuntimeWarning)
+ # LockFile only supports immediate-fail locking.
+ if flags & LOCK_NB:
+ win32file.LockFile(hfile, 0, 0, 0xffff0000, 0)
+ else:
+ # Emulate a blocking lock with a polling loop.
+ import time
+ while 1:
+ # Attempt a lock.
+ try:
+ win32file.LockFile(hfile, 0, 0, 0xffff0000, 0)
+ break
+ except win32file.error, e:
+ # Propagate upwards all exceptions other than lock violation.
+ if e[0] != winerror.ERROR_LOCK_VIOLATION:
+ raise e
+ # Sleep and poll again.
+ time.sleep(0.1)
+ # TODO: should this return the result of the lock?
+
+ def unlock(file):
+ hfile = win32file._get_osfhandle(file.fileno())
+ # UnlockFileEx is not supported on all Win32 platforms (Win95, Win98, WinME).
+ # If it's not supported, win32file will raise an api_error exception.
+ try:
+ win32file.UnlockFileEx(hfile, 0, 0xffff0000, __overlapped)
+ except win32file.error, e:
+ import winerror
+ # Propagate upwards all exceptions other than not-implemented.
+ if e[0] != winerror.ERROR_CALL_NOT_IMPLEMENTED:
+ raise e
+
+ # UnlockFileEx is not supported. Use UnlockFile.
+ # Care: the low/high length params are reversed compared to UnLockFileEx.
+ win32file.UnlockFile(hfile, 0, 0, 0xffff0000, 0)
elif os.name =='posix':
- def lock(file, flags):
- fcntl.flock(file.fileno(), flags)
+ def lock(file, flags):
+ fcntl.flock(file.fileno(), flags)
+ # TODO: should this return the result of the lock?
- def unlock(file):
- fcntl.flock(file.fileno(), fcntl.LOCK_UN)
+ def unlock(file):
+ fcntl.flock(file.fileno(), fcntl.LOCK_UN)
if __name__ == '__main__':
- from time import time, strftime, localtime
- import sys
- import portalocker
+ from time import time, strftime, localtime
+ import sys
+ import portalocker
- log = open('log.txt', "a+")
- portalocker.lock(log, portalocker.LOCK_EX)
+ log = open('log.txt', "a+")
+ portalocker.lock(log, portalocker.LOCK_EX)
- timestamp = strftime("%m/%d/%Y %H:%M:%S\n", localtime(time()))
- log.write( timestamp )
+ timestamp = strftime("%m/%d/%Y %H:%M:%S\n", localtime(time()))
+ log.write( timestamp )
- print "Wrote lines. Hit enter to release lock."
- dummy = sys.stdin.readline()
+ print "Wrote lines. Hit enter to release lock."
+ dummy = sys.stdin.readline()
- log.close()
+ log.close()