Comment 3 for bug 872558

Revision history for this message
Cedric Brandily (cbrandily) wrote :

My feedback (with a better understanding of greenthread/coroutines (like eventlet)) :

- utils.synchronized is working well if we only use it with coroutines (greenthread) because eventlet implies constraints on where switch between greenthreads append
- utils.synchronized is not working for real Threads ...
==> so impose to never use Threads or change utils.synchronized

I got trouble with the condition in my proposal (coroutine liveness trouble) so i use weak references instead in LockByKey ( ... cleaning embedded :)). The code is more simple

class LockByKey(object):
    '''
    usage:
    locks = LockByKey()
    with locks('using __call__ + with'):
        pass
    with locks['using __getitem__ + with']:
        pass
    '''
    def __init__(self, lock_factory=None):
        self._lock_factory = lock_factory or threading.Lock
        self._lock = self._lock_factory()
        self._weaklocks = weakref.WeakValueDictionary()

    def _get_lock(self, lock_key):
        with self._lock:
            lock = self._weaklocks.get(lock_key)
            if lock is None:
                self._weaklocks[lock_key] = lock = self._lock_factory()
        return lock

    @contextlib.contextmanager
    def __call__(self, lock_key):
        with self._get_lock(lock_key):
            yield
    __getitem__ = __call__