| # Gaudi Framework, version v25r0 |

Home |  | Generated: Mon Feb 17 2014

- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
locker.py
Go to the documentation of this file.
1 ##########################################################
2 ## stolen and (slighty) adapted from:
3 ## http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/65203
4 ##
5
6 import os, time
7
8 if os.name == 'nt':
9 import msvcrt
10 elif os.name == 'posix':
11 import fcntl
12 LOCK_EX = fcntl.F_WRLCK
13 LOCK_SH = fcntl.F_RDLCK
14 LOCK_NB = fcntl.F_UNLCK
15 else:
16 raise RuntimeError("Locker only defined for nt and posix platforms")
17
18 if os.name == 'nt':
19 def lock(file):
20 """
21 Lock first 10 bytes of a file.
22 """
23 pos = file.tell() # remember current position
24 file.seek(0)
25 # By default, python tries about 10 times, then throws an exception.
26 # We want to wait forever.
27 acquired = False
28 while not acquired:
29 try:
30 msvcrt.locking(file.fileno(),msvcrt.LK_LOCK,10)
31 acquired = True
32 except IOError, x:
33 if x.errno != 36: # 36, AKA 'Resource deadlock avoided', is normal
34 raise
35 file.seek(pos) # reset position
36
37 def unlock(file):
38 """
39 Unlock first 10 bytes of a file.
40 """
41 pos = file.tell() # remember current position
42 file.seek(0)
43 msvcrt.locking(file.fileno(),msvcrt.LK_UNLCK,10)
44 file.seek(pos) # reset position
45
46 elif os.name =='posix':
47 import socket, errno
48
49 def _tmpFileName(fileName):
50 return "%s.%s.%d" % ( fileName, socket.gethostname(), os.getpid() )
51 def _lckFileName(fileName):
52 return "%s.lock" % fileName
53
54 def _linkCount( lockFileName ):
55 try:
56 return os.stat(lockFileName).st_nlink
57 except OSError, e:
58 if e.errno != errno.ENOENT:
59 raise
60 return -1
61 def _read(fileName):
62 try:
63 fp = open(fileName)
64 try: readFileName = fp.read()
65 finally: fp.close()
66 return readFileName
67 except EnvironmentError, e:
68 if e.errno != errno.ENOENT:
69 raise
70 return None
71
72 def _sleep(): time.sleep(8)
73
74 def lock(file):
75 fileName = file.name
76 tmpFileName = _tmpFileName(fileName)
77 fp = open( tmpFileName, "w" )
78 fp.write( tmpFileName )
79 fp.close()
80
81 lockFileName = _lckFileName( fileName )
82 while True:
83 if _linkCount(lockFileName) != -1: _sleep()
84 try:
85 os.link( tmpFileName, lockFileName )
86 # we acquired the lock
87 return
88 except OSError, e:
89 if e.errno == errno.ENOENT:
90 pass
91 elif e.errno != errno.EEXIST:
92 os.unlink(tmpFileName)
93 raise
94 elif _linkCount( lockFileName ) != 2:
95 pass
96 elif _read(lockFileName) == tmpFileName:
97 raise
98 else:
99 # someone else owns that lock
100 pass
101 ## didn't get the lock !!
102 ## say something ?
103 #print _id_()," failed to acquire the lock ..."
104 _sleep()
105 pass
106 return
107
108 def unlock(file):
109 fileName = file.name
110 tmpFileName = _tmpFileName(fileName)
111 lockFileName = _lckFileName( fileName )
112
113 try:
114 os.unlink( lockFileName )
115 except OSError, e:
116 if e.errno != errno.ENOENT:
117 raise
118 # remove the tmp file
119 try:
120 os.unlink( tmpFileName )
121 except OSError, e:
122 if e.errno != errno.ENOENT:
123 raise
124 return
125
126 import logging
127 ## Lock a file.
128 # The file for the lock is created if it doesn't exists and it the "temporary"
129 # argument is set to True it will also be deleted when the lock is not needed.
130 # The unlocking is done in the destructor (RAII pattern).
131 class LockFile(object):
132 def __init__(self, name, temporary = False):
133 self.name = name
134 self.temporary = temporary
135 self.file = None
136 self.log = logging.getLogger("LockFile")
137 self.log.info("%s - Locking on %s", time.strftime("%Y-%m-%d_%H:%M:%S"), self.name)
138 if not os.path.exists(name):
139 mode = "w"
140 else:
141 self.temporary = False # I do not want to delete a file I didn't create
142 mode = "r+"
143 try:
144 self.file = open(self.name, mode)
145 lock(self.file)
146 except:
147 self.log.warning("Cannot acquire lock on %s", self.name)
148 def __del__(self):
149 if self.file:
150 unlock(self.file)
151 self.file.close()
152 if self.temporary:
153 try:
154 os.remove(self.name)
155 except:
156 pass
157 self.log.info("%s - Lock on %s released", time.strftime("%Y-%m-%d_%H:%M:%S"), self.name)
158