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