Gaudi Framework, version v24r2

Home   Generated: Wed Dec 4 2013
 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 

Generated at Wed Dec 4 2013 14:33:10 for Gaudi Framework, version v24r2 by Doxygen version 1.8.2 written by Dimitri van Heesch, © 1997-2004