Skip to content

Instantly share code, notes, and snippets.

@snoack
Created October 2, 2012 10:53
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save snoack/3818148 to your computer and use it in GitHub Desktop.
Save snoack/3818148 to your computer and use it in GitHub Desktop.
Shared/exclusive lock implementation on top of pipes and UNIX file locks
import os
import fcntl
import errno
from multiprocessing.util import register_after_fork
def _reset_level_after_fork(lock):
lock._level = 0
class _ShrdExclLock(object):
def __init__(self, fd):
self._fd = fd
self._level = 0
register_after_fork(self, _reset_level_after_fork)
def __del__(self):
os.close(self._fd)
def acquire(self, blocking=True):
try:
fcntl.lockf(self._fd, self._lock_mode | (not blocking and fcntl.LOCK_NB))
except IOError as e:
if e.errno == errno.EAGIN:
return False
raise
self._level += 1
return True
def release(self):
if self._level == 0:
raise ValueError('lock released too many times')
self._level -= 1
if self._level == 0:
fcntl.lockf(self._fd, fcntl.LOCK_UN)
def __enter__(self):
self.acquire()
return self
def __exit__(self, exc_type, exc_value, tb):
self.release()
class _ShrdLock(_ShrdExclLock):
_lock_mode = fcntl.LOCK_SH
class _ExclLock(_ShrdExclLock):
_lock_mode = fcntl.LOCK_EX
def ShrdExclLock():
read_end, write_end = os.pipe()
return (_ShrdLock(read_end), _ExclLock(write_end))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment