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.
37
from trace import mutter, note, warning
38
from errors import LockError
42
LOCK_SH = fcntl.LOCK_SH
43
LOCK_EX = fcntl.LOCK_EX
44
LOCK_NB = fcntl.LOCK_NB
53
fcntl.flock(f, fcntl.LOCK_UN)
59
import win32con, win32file, pywintypes
60
LOCK_SH = 0 # the default
61
LOCK_EX = win32con.LOCKFILE_EXCLUSIVE_LOCK
62
LOCK_NB = win32con.LOCKFILE_FAIL_IMMEDIATELY
67
hfile = win32file._get_osfhandle(f.fileno())
69
hfile = win32file._get_osfhandle(f)
70
overlapped = pywintypes.OVERLAPPED()
71
win32file.LockFileEx(hfile, flags, 0, 0x7fff0000, overlapped)
78
hfile = win32file._get_osfhandle(f.fileno())
80
hfile = win32file._get_osfhandle(f)
81
overlapped = pywintypes.OVERLAPPED()
82
win32file.UnlockFileEx(hfile, 0, 0x7fff0000, overlapped)
88
# Unfortunately, msvcrt.locking() doesn't distinguish between
89
# read locks and write locks. Also, the way the combinations
90
# work to get non-blocking is not the same, so we
91
# have to write extra special functions here.
99
# Unfortunately, msvcrt.LK_RLCK is equivalent to msvcrt.LK_LOCK
100
# according to the comments, LK_RLCK is open the lock for writing.
102
# Unfortunately, msvcrt.locking() also has the side effect that it
103
# will only block for 10 seconds at most, and then it will throw an
104
# exception, this isn't terrible, though.
111
fpos = os.lseek(fn, 0,0)
116
lock_mode = msvcrt.LK_NBLCK
118
lock_mode = msvcrt.LK_LOCK
119
elif flags & LOCK_EX:
121
lock_mode = msvcrt.LK_NBRLCK
123
lock_mode = msvcrt.LK_RLCK
125
raise ValueError('Invalid lock mode: %r' % flags)
127
msvcrt.locking(fn, lock_mode, -1)
129
os.lseek(fn, fpos, 0)
141
fpos = os.lseek(fn, 0,0)
145
msvcrt.locking(fn, msvcrt.LK_UNLCK, -1)
147
os.lseek(fn, fpos, 0)
151
from warnings import Warning
153
warning("please write a locking method for platform %r" % sys.platform)
155
# Creating no-op lock/unlock for now