Skip to content

Instantly share code, notes, and snippets.

@snoack
Created Oct 2, 2012
Embed
What would you like to do?
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