00001
00002
00003
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()
00024 file.seek(0)
00025
00026
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:
00034 raise
00035 file.seek(pos)
00036
00037 def unlock(file):
00038 """
00039 Unlock first 10 bytes of a file.
00040 """
00041 pos = file.tell()
00042 file.seek(0)
00043 msvcrt.locking(file.fileno(),msvcrt.LK_UNLCK,10)
00044 file.seek(pos)
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
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
00100 pass
00101
00102
00103
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
00119 try:
00120 os.unlink( tmpFileName )
00121 except OSError, e:
00122 if e.errno != errno.ENOENT:
00123 raise
00124 return
00125
00126