|
1 """ |
|
2 Portable file locking utilities. |
|
3 |
|
4 Based partially on example by Jonathan Feignberg <jdf@pobox.com> in the Python |
|
5 Cookbook, licensed under the Python Software License. |
|
6 |
|
7 http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/65203 |
|
8 |
|
9 Example Usage:: |
|
10 |
|
11 >>> from django.core.files import locks |
|
12 >>> f = open('./file', 'wb') |
|
13 >>> locks.lock(f, locks.LOCK_EX) |
|
14 >>> f.write('Django') |
|
15 >>> f.close() |
|
16 """ |
|
17 |
|
18 __all__ = ('LOCK_EX','LOCK_SH','LOCK_NB','lock','unlock') |
|
19 |
|
20 system_type = None |
|
21 |
|
22 try: |
|
23 import win32con |
|
24 import win32file |
|
25 import pywintypes |
|
26 LOCK_EX = win32con.LOCKFILE_EXCLUSIVE_LOCK |
|
27 LOCK_SH = 0 |
|
28 LOCK_NB = win32con.LOCKFILE_FAIL_IMMEDIATELY |
|
29 __overlapped = pywintypes.OVERLAPPED() |
|
30 system_type = 'nt' |
|
31 except (ImportError, AttributeError): |
|
32 pass |
|
33 |
|
34 try: |
|
35 import fcntl |
|
36 LOCK_EX = fcntl.LOCK_EX |
|
37 LOCK_SH = fcntl.LOCK_SH |
|
38 LOCK_NB = fcntl.LOCK_NB |
|
39 system_type = 'posix' |
|
40 except (ImportError, AttributeError): |
|
41 pass |
|
42 |
|
43 def fd(f): |
|
44 """Get a filedescriptor from something which could be a file or an fd.""" |
|
45 return hasattr(f, 'fileno') and f.fileno() or f |
|
46 |
|
47 if system_type == 'nt': |
|
48 def lock(file, flags): |
|
49 hfile = win32file._get_osfhandle(fd(file)) |
|
50 win32file.LockFileEx(hfile, flags, 0, -0x10000, __overlapped) |
|
51 |
|
52 def unlock(file): |
|
53 hfile = win32file._get_osfhandle(fd(file)) |
|
54 win32file.UnlockFileEx(hfile, 0, -0x10000, __overlapped) |
|
55 elif system_type == 'posix': |
|
56 def lock(file, flags): |
|
57 fcntl.lockf(fd(file), flags) |
|
58 |
|
59 def unlock(file): |
|
60 fcntl.lockf(fd(file), fcntl.LOCK_UN) |
|
61 else: |
|
62 # File locking is not supported. |
|
63 LOCK_EX = LOCK_SH = LOCK_NB = None |
|
64 |
|
65 # Dummy functions that don't do anything. |
|
66 def lock(file, flags): |
|
67 pass |
|
68 |
|
69 def unlock(file): |
|
70 pass |