codekingpro/portable-devtools
114k
1from eventlet import hubs2from eventlet.semaphore import Semaphore3 4 5class Lock(Semaphore):6 7 """A lock.8 This is API-compatible with :class:`threading.Lock`.9 10 It is a context manager, and thus can be used in a with block::11 12 lock = Lock()13 with lock:14 do_some_stuff()15 """16 17 def release(self, blocking=True):18 """Modify behaviour vs :class:`Semaphore` to raise a RuntimeError19 exception if the value is greater than zero. This corrects behaviour20 to realign with :class:`threading.Lock`.21 """22 if self.counter > 0:23 raise RuntimeError("release unlocked lock")24 25 # Consciously *do not* call super().release(), but instead inline26 # Semaphore.release() here. We've seen issues with logging._lock27 # deadlocking because garbage collection happened to run mid-release28 # and eliminating the extra stack frame should help prevent that.29 # See https://github.com/eventlet/eventlet/issues/74230 self.counter += 131 if self._waiters:32 hubs.get_hub().schedule_call_global(0, self._do_acquire)33 return True34 35 def _at_fork_reinit(self):36 self.counter = 137 self._waiters.clear()38 