Commit aae48cb5 authored by payno's avatar payno Committed by payno
Browse files

[utils] add SharedLockPool for HDFFile

parent aeeb2d5b
......@@ -30,6 +30,8 @@ __date__ = "02/10/2017"
import functools
from contextlib import contextmanager, ExitStack
import threading
def _docstring(dest, origin):
......@@ -65,3 +67,55 @@ def docstring(origin):
If the origin class has not method n case the
"""
return functools.partial(_docstring, origin=origin)
class SharedLockPool:
"""
Allows to acquire locks identified by name (hashable type) recursively.
"""
def __init__(self):
self.__locks = {}
self.__locks_mutex = threading.Semaphore(value=1)
def __len__(self):
return len(self.__locks)
@property
def names(self):
return list(self.__locks.keys())
@contextmanager
def _modify_locks(self):
self.__locks_mutex.acquire()
try:
yield self.__locks
finally:
self.__locks_mutex.release()
@contextmanager
def acquire(self, name):
with self._modify_locks() as locks:
lock = locks.get(name, None)
if lock is None:
locks[name] = lock = threading.RLock()
lock.acquire()
try:
yield
finally:
lock.release()
with self._modify_locks() as locks:
locks.pop(name)
@contextmanager
def acquire_context_creation(self, name, contextmngr, *args, **kwargs):
"""
Acquire lock only during context creation.
This can be used for example to protect the opening of a file
but not hold the lock while the file is open.
"""
with ExitStack() as stack:
with self.acquire(name):
ret = stack.enter_context(contextmngr(*args, **kwargs))
yield ret
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment