Package instant :: Module locking
[hide private]
[frames] | no frames]

Source Code for Module instant.locking

 1  """File locking for the cache system, to avoid problems 
 2  when multiple processes work with the same module. 
 3  Only works on UNIX systems.""" 
 4   
 5  import os.path 
 6  from output import instant_error, instant_assert, instant_debug 
 7  from paths import validate_cache_dir 
 8   
 9  try: 
10      import fcntl 
11  except: 
12      fcntl = None 
13   
14  # Keeping an overview of locks currently held, 
15  # to avoid deadlocks within a single process. 
16  _lock_names = {} # lock.fileno() -> lockname 
17  _lock_files = {} # lockname -> lock 
18  _lock_count = {} # lockname -> number of times this lock has been aquired and not yet released 
19   
20  if fcntl: 
21 - def get_lock(cache_dir, module_name):
22 "Get a new file lock." 23 global _lock_names, _lock_files, _lock_count 24 25 lockname = module_name + ".lock" 26 count = _lock_count.get(lockname, 0) 27 28 instant_debug("Acquiring lock %s, count is %d." % (lockname, count)) 29 30 if count == 0: 31 cache_dir = validate_cache_dir(cache_dir) 32 lock = open(os.path.join(cache_dir, lockname), "w") 33 fcntl.flock(lock.fileno(), fcntl.LOCK_EX) 34 _lock_names[lock.fileno()] = lockname 35 _lock_files[lockname] = lock 36 else: 37 lock = _lock_files[lockname] 38 39 _lock_count[lockname] = count + 1 40 return lock
41
42 - def release_lock(lock):
43 "Release a lock currently held by Instant." 44 global _lock_names, _lock_files, _lock_count 45 46 lockname = _lock_names[lock.fileno()] 47 count = _lock_count[lockname] 48 49 instant_debug("Releasing lock %s, count is %d." % (lockname, count)) 50 51 instant_assert(count > 0, "Releasing lock that Instant is supposedly not holding.") 52 instant_assert(lock is _lock_files[lockname], "Lock mismatch, might be something wrong in locking logic.") 53 54 del _lock_files[lockname] 55 del _lock_names[lock.fileno()] 56 _lock_count[lockname] = count - 1 57 58 fcntl.flock(lock.fileno(), fcntl.LOCK_UN) 59 lock.close()
60
61 - def release_all_locks():
62 "Release all locks currently held by Instant." 63 locks = _lock_files.values() 64 for lock in locks: 65 release_lock(lock) 66 instant_assert(all(_lock_count[lockname] == 0 for lockname in _lock_count), "Lock counts not zero after releasing all locks.")
67 68 else: 69 # Windows systems have no fcntl, implement these otherwise if locking is needed on windows
70 - def get_lock(cache_dir, module_name):
71 return None
72
73 - def release_lock(lock):
74 pass
75