| Classes | Job Modules | Data Objects | Services | Algorithms | Tools | Packages | Directories | Tracs |

In This Package:

locker.py

Go to the documentation of this file.
00001 ##########################################################
00002 ## stolen and (slighty) adapted from:
00003 ##  http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/65203
00004 ##
00005 
00006 import os, sys 
00007 
00008 if os.name == 'nt':
00009     import msvcrt
00010 elif os.name == 'posix':
00011     import fcntl
00012     LOCK_EX = fcntl.F_WRLCK
00013     LOCK_SH = fcntl.F_RDLCK
00014     LOCK_NB = fcntl.F_UNLCK
00015 else:
00016     raise RuntimeError("Locker only defined for nt and posix platforms")
00017 
00018 if os.name == 'nt':
00019     def lock(file):
00020         """
00021         Lock first 10 bytes of a file.
00022         """ 
00023         pos = file.tell() # remember current position
00024         file.seek(0)
00025         # By default, python tries about 10 times, then throws an exception.
00026         # We want to wait forever.
00027         acquired = False
00028         while not acquired:
00029             try:
00030                 msvcrt.locking(file.fileno(),msvcrt.LK_LOCK,10)
00031                 acquired = True
00032             except IOError, x:
00033                 if x.errno != 36: # 36, AKA 'Resource deadlock avoided', is normal
00034                     raise
00035         file.seek(pos) # reset position
00036 
00037     def unlock(file):
00038         """
00039         Unlock first 10 bytes of a file.
00040         """ 
00041         pos = file.tell() # remember current position
00042         file.seek(0)
00043         msvcrt.locking(file.fileno(),msvcrt.LK_UNLCK,10)
00044         file.seek(pos) # reset position
00045 
00046 elif os.name =='posix':
00047     import socket,errno,time
00048 
00049     def _tmpFileName(fileName):
00050         return "%s.%s.%d" % ( fileName, socket.gethostname(), os.getpid() )
00051     def _lckFileName(fileName):
00052         return "%s.lock" % fileName
00053 
00054     def _linkCount( lockFileName ):
00055         try:
00056             return os.stat(lockFileName).st_nlink
00057         except OSError, e:
00058             if e.errno != errno.ENOENT:
00059                 raise
00060             return -1
00061     def _read(fileName):
00062         try:
00063             fp = open(fileName)
00064             try:     readFileName = fp.read()
00065             finally: fp.close()
00066             return readFileName
00067         except EnvironmentError, e:
00068             if e.errno != errno.ENOENT:
00069                 raise
00070             return None
00071             
00072     def _sleep(): time.sleep(8)
00073 
00074     def lock(file):
00075         fileName = file.name
00076         tmpFileName = _tmpFileName(fileName)
00077         fp = open( tmpFileName, "w" )
00078         fp.write( tmpFileName )
00079         fp.close()
00080 
00081         lockFileName = _lckFileName( fileName )
00082         while True:
00083             if _linkCount(lockFileName) != -1: _sleep()
00084             try:
00085                 os.link( tmpFileName, lockFileName )
00086                 # we acquired the lock
00087                 return
00088             except OSError, e:
00089                 if e.errno == errno.ENOENT:
00090                     pass
00091                 elif e.errno != errno.EEXIST:
00092                     os.unlink(tmpFileName)
00093                     raise
00094                 elif _linkCount( lockFileName ) != 2:
00095                     pass
00096                 elif _read(lockFileName) == tmpFileName:
00097                     raise
00098                 else:
00099                     # someone else owns that lock
00100                     pass
00101             ## didn't get the lock !!
00102             ## say something ?
00103             #print _id_()," failed to acquire the lock ..."
00104             _sleep()
00105             pass
00106         return
00107     
00108     def unlock(file):
00109         fileName = file.name
00110         tmpFileName  = _tmpFileName(fileName)
00111         lockFileName = _lckFileName( fileName )
00112 
00113         try:
00114             os.unlink( lockFileName )
00115         except OSError, e:
00116             if e.errno != errno.ENOENT:
00117                 raise
00118         # remove the tmp file
00119         try:
00120             os.unlink( tmpFileName )
00121         except OSError, e:
00122             if e.errno != errno.ENOENT:
00123                 raise
00124         return
00125     
00126                 
| Classes | Job Modules | Data Objects | Services | Algorithms | Tools | Packages | Directories | Tracs |

Generated on Mon Apr 11 19:56:51 2011 for GaudiPolicy by doxygen 1.4.7