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 else:
13  raise RuntimeError("Locker only defined for nt and posix platforms")
14 
15 if os.name == 'nt':
16  def lock(file):
17  """
18  Lock first 10 bytes of a file.
19  """
20  pos = file.tell() # remember current position
21  file.seek(0)
22  # By default, python tries about 10 times, then throws an exception.
23  # We want to wait forever.
24  acquired = False
25  while not acquired:
26  try:
27  msvcrt.locking(file.fileno(),msvcrt.LK_LOCK,10)
28  acquired = True
29  except IOError, x:
30  if x.errno != 36: # 36, AKA 'Resource deadlock avoided', is normal
31  raise
32  file.seek(pos) # reset position
33 
34  def unlock(file):
35  """
36  Unlock first 10 bytes of a file.
37  """
38  pos = file.tell() # remember current position
39  file.seek(0)
40  msvcrt.locking(file.fileno(),msvcrt.LK_UNLCK,10)
41  file.seek(pos) # reset position
42 
43 elif os.name =='posix':
44  def lock(file) :
45  # Lock with a simple call to lockf() - this blocks until the lock is aquired
46  try:
47  fcntl.lockf( file, fcntl.LOCK_EX )
48  except IOError, exc_value:
49  print "Problem when trying to lock {0}, IOError {1}".format(file, exc_value[0])
50  raise
51  return
52 
53  def unlock(file):
54  fcntl.lockf( file, fcntl.LOCK_UN )
55  return
56 
57 
58 import logging
59 ## Lock a file.
60 # The file for the lock is created if it doesn't exists and it the "temporary"
61 # argument is set to True it will also be deleted when the lock is not needed.
62 # The unlocking is done in the destructor (RAII pattern).
63 class LockFile(object):
64  def __init__(self, name, temporary = False):
65  self.name = name
66  self.temporary = temporary
67  self.file = None
68  self.log = logging.getLogger("LockFile")
69  self.log.info("%s - Locking on %s", time.strftime("%Y-%m-%d_%H:%M:%S"), self.name)
70  if not os.path.exists(name):
71  mode = "w"
72  else:
73  self.temporary = False # I do not want to delete a file I didn't create
74  mode = "r+"
75  try:
76  self.file = open(self.name, mode)
77  lock(self.file)
78  except:
79  self.log.warning("Cannot acquire lock on %s", self.name)
80 
81  def __del__(self):
82  if self.file:
83  unlock(self.file)
84  self.file.close()
85  if self.temporary:
86  try:
87  os.remove(self.name)
88  except:
89  pass
90  self.log.info("%s - Lock on %s released", time.strftime("%Y-%m-%d_%H:%M:%S"), self.name)
91  self.file = None # Don't unlock twice!
92 
93 
94  # The following methods are needed to allow the use of python's "with" statement, i.e,
95  # with LockFile("myFile") as mylock:
96  def __enter__(self):
97  return self
98 
99  def __exit__(self, type, value, traceback):
100  self.__del__()
101 
GAUDI_API std::string format(const char *,...)
MsgStream format utility "a la sprintf(...)".
Definition: MsgStream.cpp:133
def __exit__
Definition: locker.py:99
def lock
Definition: locker.py:16
Lock a file.
Definition: locker.py:63
def __init__
Definition: locker.py:64
def unlock
Definition: locker.py:34
def __enter__
Definition: locker.py:96