Poodletooth-iLand/panda/python/Lib/site-packages/gevent/lock.py
2015-04-07 17:08:36 -04:00

118 lines
3 KiB
Python

# Copyright (c) 2009-2012 Denis Bilenko. See LICENSE for details.
"""Locking primitives"""
from gevent.hub import getcurrent
from gevent._semaphore import Semaphore
__all__ = ['Semaphore', 'DummySemaphore', 'BoundedSemaphore', 'RLock']
class DummySemaphore(object):
# XXX what is this used for?
"""A Semaphore initialized with "infinite" initial value. None of its methods ever block."""
def __str__(self):
return '<%s>' % self.__class__.__name__
def locked(self):
return False
def release(self):
pass
def rawlink(self, callback):
# XXX should still work and notify?
pass
def unlink(self, callback):
pass
def wait(self, timeout=None):
pass
def acquire(self, blocking=True, timeout=None):
pass
def __enter__(self):
pass
def __exit__(self, typ, val, tb):
pass
class BoundedSemaphore(Semaphore):
"""A bounded semaphore checks to make sure its current value doesn't exceed its initial value.
If it does, ``ValueError`` is raised. In most situations semaphores are used to guard resources
with limited capacity. If the semaphore is released too many times it's a sign of a bug.
If not given, *value* defaults to 1."""
def __init__(self, value=1):
Semaphore.__init__(self, value)
self._initial_value = value
def release(self):
if self.counter >= self._initial_value:
raise ValueError("Semaphore released too many times")
return Semaphore.release(self)
class RLock(object):
def __init__(self):
self._block = Semaphore(1)
self._owner = None
self._count = 0
def __repr__(self):
return "<%s at 0x%x _block=%s _count=%r _owner=%r)>" % (
self.__class__.__name__,
id(self),
self._block,
self._count,
self._owner)
def acquire(self, blocking=1):
me = getcurrent()
if self._owner is me:
self._count = self._count + 1
return 1
rc = self._block.acquire(blocking)
if rc:
self._owner = me
self._count = 1
return rc
def __enter__(self):
return self.acquire()
def release(self):
if self._owner is not getcurrent():
raise RuntimeError("cannot release un-aquired lock")
self._count = count = self._count - 1
if not count:
self._owner = None
self._block.release()
def __exit__(self, typ, value, tb):
self.release()
# Internal methods used by condition variables
def _acquire_restore(self, count_owner):
count, owner = count_owner
self._block.acquire()
self._count = count
self._owner = owner
def _release_save(self):
count = self._count
self._count = 0
owner = self._owner
self._owner = None
self._block.release()
return (count, owner)
def _is_owned(self):
return self._owner is getcurrent()