Files
OpenMTC/build/lib/futile/multiprocess/RWLock.py
Christian Klopp e9af73dfe8 initial commit
2017-11-07 14:41:38 +01:00

83 lines
1.5 KiB
Python

'''
Created on 30.04.2011
@author: kca
'''
import os
from fcntl import lockf, LOCK_EX, LOCK_SH, LOCK_UN
from contextlib import contextmanager
from futile.signal import timeout
class RWLock(object):
def __init__(self, path = None, threadsafe = True, *args, **kw):
if not path:
raise NotImplementedError()
if not os.path.exists(path):
open(path, "a").close()
self.__path = path
if threadsafe:
import threading
self.__local = threading.local()
else:
class Local(object):
pass
self.__local = Local
self.__local.f = None
@contextmanager
def read_transaction(self, timeout = None):
self.read_acquire(timeout = timeout)
try:
yield
finally:
self.read_release()
pass
pass
@contextmanager
def write_transaction(self, timeout = None):
self.write_acquire(timeout = timeout)
try:
yield
finally:
self.write_release()
def __acquire(self, fmode, lmode, to):
assert getattr(self.__local, "f", None) is None
f = open(self.__path, fmode)
try:
if timeout:
with timeout(to):
lockf(f, lmode)
else:
lockf(f, lmode)
except:
f.close()
raise
self.__local.f = f
return f
def read_acquire(self, timeout = None):
return self.__acquire("r", LOCK_SH, timeout)
def read_release(self):
with self.__local.f as f:
self.__local.f = None
lockf(f, LOCK_UN)
write_release = read_release
def write_acquire(self, timeout = None):
return self.__acquire("a", LOCK_EX, timeout)
__enter__ = write_acquire
def __exit__(self, *args):
self.write_release()