1
# Copyright (C) 2005 Canonical Ltd
3
# This program is free software; you can redistribute it and/or modify
4
# it under the terms of the GNU General Public License as published by
5
# the Free Software Foundation; either version 2 of the License, or
6
# (at your option) any later version.
8
# This program is distributed in the hope that it will be useful,
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
# GNU General Public License for more details.
13
# You should have received a copy of the GNU General Public License
14
# along with this program; if not, write to the Free Software
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20
This only does local locking using OS locks for now.
22
This module causes two methods, lock() and unlock() to be defined in
23
any way that works on the current platform.
25
It is not specified whether these locks are reentrant (i.e. can be
26
taken repeatedly by a single process) or whether they exclude
27
different threads in a single process.
29
Eventually we may need to use some kind of lock representation that
30
will work on a dumb filesystem without actual locking primitives."""
36
from trace import mutter, note, warning
38
class LockError(Exception):
39
"""All exceptions from the lock/unlock functions should be from this exception class.
40
They will be translated as necessary. The original exception is available as e.original_error
42
def __init__(self, e=None):
43
self.original_error = e
45
Exception.__init__(self, e)
47
Exception.__init__(self)
51
LOCK_SH = fcntl.LOCK_SH
52
LOCK_EX = fcntl.LOCK_EX
53
LOCK_NB = fcntl.LOCK_NB
62
fcntl.flock(f, fcntl.LOCK_UN)
68
import win32con, win32file, pywintypes
69
LOCK_SH = 0 # the default
70
LOCK_EX = win32con.LOCKFILE_EXCLUSIVE_LOCK
71
LOCK_NB = win32con.LOCKFILE_FAIL_IMMEDIATELY
76
hfile = win32file._get_osfhandle(f.fileno())
78
hfile = win32file._get_osfhandle(f)
79
overlapped = pywintypes.OVERLAPPED()
80
win32file.LockFileEx(hfile, flags, 0, 0x7fff0000, overlapped)
87
hfile = win32file._get_osfhandle(f.fileno())
89
hfile = win32file._get_osfhandle(f)
90
overlapped = pywintypes.OVERLAPPED()
91
win32file.UnlockFileEx(hfile, 0, 0x7fff0000, overlapped)
97
# Unfortunately, msvcrt.locking() doesn't distinguish between
98
# read locks and write locks. Also, the way the combinations
99
# work to get non-blocking is not the same, so we
100
# have to write extra special functions here.
108
# Unfortunately, msvcrt.LK_RLCK is equivalent to msvcrt.LK_LOCK
109
# according to the comments, LK_RLCK is open the lock for writing.
111
# Unfortunately, msvcrt.locking() also has the side effect that it
112
# will only block for 10 seconds at most, and then it will throw an
113
# exception, this isn't terrible, though.
120
fpos = os.lseek(fn, 0,0)
125
lock_mode = msvcrt.LK_NBLCK
127
lock_mode = msvcrt.LK_LOCK
128
elif flags & LOCK_EX:
130
lock_mode = msvcrt.LK_NBRLCK
132
lock_mode = msvcrt.LK_RLCK
134
raise ValueError('Invalid lock mode: %r' % flags)
136
msvcrt.locking(fn, lock_mode, -1)
138
os.lseek(fn, fpos, 0)
150
fpos = os.lseek(fn, 0,0)
154
msvcrt.locking(fn, msvcrt.LK_UNLCK, -1)
156
os.lseek(fn, fpos, 0)
160
from warnings import Warning
162
warning("please write a locking method for platform %r" % sys.platform)
164
# Creating no-op lock/unlock for now