Package gluon :: Module portalocker
[hide private]
[frames] | no frames]

Source Code for Module gluon.portalocker

  1  #!/usr/bin/env python 
  2  # -*- coding: utf-8 -*- 
  3  # portalocker.py 
  4  # Cross-platform (posix/nt) API for flock-style file locking. 
  5  #                  Requires python 1.5.2 or better. 
  6   
  7  """ 
  8  Cross-platform (posix/nt) API for flock-style file locking. 
  9   
 10  Synopsis: 
 11   
 12     import portalocker 
 13     file = open(\"somefile\", \"r+\") 
 14     portalocker.lock(file, portalocker.LOCK_EX) 
 15     file.seek(12) 
 16     file.write(\"foo\") 
 17     file.close() 
 18   
 19  If you know what you're doing, you may choose to 
 20   
 21     portalocker.unlock(file) 
 22   
 23  before closing the file, but why? 
 24   
 25  Methods: 
 26   
 27     lock( file, flags ) 
 28     unlock( file ) 
 29   
 30  Constants: 
 31   
 32     LOCK_EX 
 33     LOCK_SH 
 34     LOCK_NB 
 35   
 36  I learned the win32 technique for locking files from sample code 
 37  provided by John Nielsen <nielsenjf@my-deja.com> in the documentation 
 38  that accompanies the win32 modules. 
 39   
 40  Author: Jonathan Feinberg <jdf@pobox.com> 
 41  Version: $Id: portalocker.py,v 1.3 2001/05/29 18:47:55 Administrator Exp $ 
 42  """ 
 43   
 44  import logging 
 45  import platform 
 46  logger = logging.getLogger("web2py") 
 47   
 48  os_locking = None 
 49  try: 
 50      import google.appengine 
 51      os_locking = 'gae' 
 52  except: 
 53      try: 
 54          import fcntl 
 55          os_locking = 'posix' 
 56      except: 
 57          try: 
 58              import win32con 
 59              import win32file 
 60              import pywintypes 
 61              os_locking = 'windows' 
 62          except: 
 63              pass 
 64   
 65  if os_locking == 'windows': 
 66      LOCK_EX = win32con.LOCKFILE_EXCLUSIVE_LOCK 
 67      LOCK_SH = 0  # the default 
 68      LOCK_NB = win32con.LOCKFILE_FAIL_IMMEDIATELY 
 69   
 70      # is there any reason not to reuse the following structure? 
 71   
 72      __overlapped = pywintypes.OVERLAPPED() 
 73   
74 - def lock(file, flags):
75 hfile = win32file._get_osfhandle(file.fileno()) 76 win32file.LockFileEx(hfile, flags, 0, 0x7fff0000, __overlapped)
77
78 - def unlock(file):
79 hfile = win32file._get_osfhandle(file.fileno()) 80 win32file.UnlockFileEx(hfile, 0, 0x7fff0000, __overlapped)
81 82 83 elif os_locking == 'posix': 84 LOCK_EX = fcntl.LOCK_EX 85 LOCK_SH = fcntl.LOCK_SH 86 LOCK_NB = fcntl.LOCK_NB 87
88 - def lock(file, flags):
89 fcntl.flock(file.fileno(), flags)
90
91 - def unlock(file):
92 fcntl.flock(file.fileno(), fcntl.LOCK_UN)
93 94 95 else: 96 if platform.system() == 'Windows': 97 logger.error('no file locking, you must install the win32 extensions from: http://sourceforge.net/projects/pywin32/files/') 98 elif os_locking != 'gae': 99 logger.debug('no file locking, this will cause problems') 100 101 LOCK_EX = None 102 LOCK_SH = None 103 LOCK_NB = None 104
105 - def lock(file, flags):
106 pass
107
108 - def unlock(file):
109 pass
110 111
112 -class LockedFile(object):
113 - def __init__(self, filename, mode='rb'):
114 self.filename = filename 115 self.mode = mode 116 self.file = None 117 if 'r' in mode: 118 self.file = open(filename, mode) 119 lock(self.file, LOCK_SH) 120 elif 'w' in mode or 'a' in mode: 121 self.file = open(filename, mode.replace('w', 'a')) 122 lock(self.file, LOCK_EX) 123 if not 'a' in mode: 124 self.file.seek(0) 125 self.file.truncate() 126 else: 127 raise RuntimeError("invalid LockedFile(...,mode)")
128
129 - def read(self, size=None):
130 return self.file.read() if size is None else self.file.read(size)
131
132 - def readline(self):
133 return self.file.readline()
134
135 - def readlines(self):
136 return self.file.readlines()
137
138 - def write(self, data):
139 self.file.write(data) 140 self.file.flush()
141
142 - def close(self):
143 if not self.file is None: 144 unlock(self.file) 145 self.file.close() 146 self.file = None
147
148 - def __del__(self):
149 if not self.file is None: 150 self.close()
151 152
153 -def read_locked(filename):
154 fp = LockedFile(filename, 'r') 155 data = fp.read() 156 fp.close() 157 return data
158 159
160 -def write_locked(filename, data):
161 fp = LockedFile(filename, 'w') 162 data = fp.write(data) 163 fp.close()
164 165 if __name__ == '__main__': 166 f = LockedFile('test.txt', mode='wb') 167 f.write('test ok') 168 f.close() 169 f = LockedFile('test.txt', mode='rb') 170 sys.stdout.write(f.read()+'\n') 171 f.close() 172