183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# 283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# Module implementing synchronization primitives 383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# 483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# multiprocessing/synchronize.py 583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# 683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# Copyright (c) 2006-2008, R Oudkerk 783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# All rights reserved. 883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# 983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# Redistribution and use in source and binary forms, with or without 1083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# modification, are permitted provided that the following conditions 1183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# are met: 1283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# 1383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# 1. Redistributions of source code must retain the above copyright 1483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# notice, this list of conditions and the following disclaimer. 1583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# 2. Redistributions in binary form must reproduce the above copyright 1683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# notice, this list of conditions and the following disclaimer in the 1783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# documentation and/or other materials provided with the distribution. 1883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# 3. Neither the name of author nor the names of any contributors may be 1983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# used to endorse or promote products derived from this software 2083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# without specific prior written permission. 2183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# 2283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND 2383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 2683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 3083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 3183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# SUCH DAMAGE. 3383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# 3483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 3583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh__all__ = [ 3683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 'Lock', 'RLock', 'Semaphore', 'BoundedSemaphore', 'Condition', 'Event' 3783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh ] 3883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 3983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehimport threading 4083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehimport os 4183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehimport sys 4283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 4383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehfrom time import time as _time, sleep as _sleep 4483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 4583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehimport _multiprocessing 4683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehfrom multiprocessing.process import current_process 4783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehfrom multiprocessing.util import Finalize, register_after_fork, debug 4883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehfrom multiprocessing.forking import assert_spawning, Popen 4983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 5083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# Try to import the mp.synchronize module cleanly, if it fails 5183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# raise ImportError for platforms lacking a working sem_open implementation. 5283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# See issue 3770 5383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehtry: 5483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh from _multiprocessing import SemLock 5583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehexcept (ImportError): 5683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh raise ImportError("This platform lacks a functioning sem_open" + 5783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh " implementation, therefore, the required" + 5883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh " synchronization primitives needed will not" + 5983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh " function, see issue 3770.") 6083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 6183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# 6283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# Constants 6383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# 6483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 6583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew HsiehRECURSIVE_MUTEX, SEMAPHORE = range(2) 6683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew HsiehSEM_VALUE_MAX = _multiprocessing.SemLock.SEM_VALUE_MAX 6783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 6883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# 6983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# Base class for semaphores and mutexes; wraps `_multiprocessing.SemLock` 7083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# 7183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 7283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehclass SemLock(object): 7383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 7483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh def __init__(self, kind, value, maxvalue): 7583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh sl = self._semlock = _multiprocessing.SemLock(kind, value, maxvalue) 7683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh debug('created semlock with handle %s' % sl.handle) 7783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh self._make_methods() 7883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 7983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh if sys.platform != 'win32': 8083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh def _after_fork(obj): 8183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh obj._semlock._after_fork() 8283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh register_after_fork(self, _after_fork) 8383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 8483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh def _make_methods(self): 8583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh self.acquire = self._semlock.acquire 8683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh self.release = self._semlock.release 8783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 8883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh def __enter__(self): 8983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh return self._semlock.__enter__() 9083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 9183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh def __exit__(self, *args): 9283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh return self._semlock.__exit__(*args) 9383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 9483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh def __getstate__(self): 9583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh assert_spawning(self) 9683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh sl = self._semlock 9783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh return (Popen.duplicate_for_child(sl.handle), sl.kind, sl.maxvalue) 9883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 9983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh def __setstate__(self, state): 10083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh self._semlock = _multiprocessing.SemLock._rebuild(*state) 10183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh debug('recreated blocker with handle %r' % state[0]) 10283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh self._make_methods() 10383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 10483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# 10583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# Semaphore 10683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# 10783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 10883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehclass Semaphore(SemLock): 10983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 11083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh def __init__(self, value=1): 11183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh SemLock.__init__(self, SEMAPHORE, value, SEM_VALUE_MAX) 11283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 11383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh def get_value(self): 11483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh return self._semlock._get_value() 11583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 11683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh def __repr__(self): 11783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh try: 11883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh value = self._semlock._get_value() 11983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh except Exception: 12083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh value = 'unknown' 12183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh return '<Semaphore(value=%s)>' % value 12283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 12383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# 12483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# Bounded semaphore 12583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# 12683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 12783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehclass BoundedSemaphore(Semaphore): 12883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 12983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh def __init__(self, value=1): 13083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh SemLock.__init__(self, SEMAPHORE, value, value) 13183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 13283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh def __repr__(self): 13383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh try: 13483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh value = self._semlock._get_value() 13583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh except Exception: 13683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh value = 'unknown' 13783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh return '<BoundedSemaphore(value=%s, maxvalue=%s)>' % \ 13883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh (value, self._semlock.maxvalue) 13983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 14083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# 14183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# Non-recursive lock 14283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# 14383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 14483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehclass Lock(SemLock): 14583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 14683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh def __init__(self): 14783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh SemLock.__init__(self, SEMAPHORE, 1, 1) 14883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 14983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh def __repr__(self): 15083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh try: 15183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh if self._semlock._is_mine(): 15283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh name = current_process().name 15383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh if threading.current_thread().name != 'MainThread': 15483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh name += '|' + threading.current_thread().name 15583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh elif self._semlock._get_value() == 1: 15683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh name = 'None' 15783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh elif self._semlock._count() > 0: 15883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh name = 'SomeOtherThread' 15983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh else: 16083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh name = 'SomeOtherProcess' 16183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh except Exception: 16283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh name = 'unknown' 16383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh return '<Lock(owner=%s)>' % name 16483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 16583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# 16683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# Recursive lock 16783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# 16883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 16983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehclass RLock(SemLock): 17083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 17183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh def __init__(self): 17283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh SemLock.__init__(self, RECURSIVE_MUTEX, 1, 1) 17383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 17483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh def __repr__(self): 17583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh try: 17683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh if self._semlock._is_mine(): 17783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh name = current_process().name 17883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh if threading.current_thread().name != 'MainThread': 17983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh name += '|' + threading.current_thread().name 18083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh count = self._semlock._count() 18183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh elif self._semlock._get_value() == 1: 18283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh name, count = 'None', 0 18383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh elif self._semlock._count() > 0: 18483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh name, count = 'SomeOtherThread', 'nonzero' 18583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh else: 18683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh name, count = 'SomeOtherProcess', 'nonzero' 18783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh except Exception: 18883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh name, count = 'unknown', 'unknown' 18983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh return '<RLock(%s, %s)>' % (name, count) 19083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 19183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# 19283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# Condition variable 19383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# 19483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 19583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehclass Condition(object): 19683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 19783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh def __init__(self, lock=None): 19883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh self._lock = lock or RLock() 19983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh self._sleeping_count = Semaphore(0) 20083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh self._woken_count = Semaphore(0) 20183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh self._wait_semaphore = Semaphore(0) 20283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh self._make_methods() 20383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 20483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh def __getstate__(self): 20583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh assert_spawning(self) 20683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh return (self._lock, self._sleeping_count, 20783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh self._woken_count, self._wait_semaphore) 20883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 20983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh def __setstate__(self, state): 21083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh (self._lock, self._sleeping_count, 21183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh self._woken_count, self._wait_semaphore) = state 21283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh self._make_methods() 21383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 21483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh def __enter__(self): 21583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh return self._lock.__enter__() 21683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 21783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh def __exit__(self, *args): 21883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh return self._lock.__exit__(*args) 21983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 22083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh def _make_methods(self): 22183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh self.acquire = self._lock.acquire 22283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh self.release = self._lock.release 22383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 22483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh def __repr__(self): 22583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh try: 22683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh num_waiters = (self._sleeping_count._semlock._get_value() - 22783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh self._woken_count._semlock._get_value()) 22883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh except Exception: 22983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh num_waiters = 'unkown' 23083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh return '<Condition(%s, %s)>' % (self._lock, num_waiters) 23183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 23283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh def wait(self, timeout=None): 23383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh assert self._lock._semlock._is_mine(), \ 23483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 'must acquire() condition before using wait()' 23583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 23683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh # indicate that this thread is going to sleep 23783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh self._sleeping_count.release() 23883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 23983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh # release lock 24083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh count = self._lock._semlock._count() 24183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh for i in xrange(count): 24283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh self._lock.release() 24383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 24483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh try: 24583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh # wait for notification or timeout 24683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh self._wait_semaphore.acquire(True, timeout) 24783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh finally: 24883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh # indicate that this thread has woken 24983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh self._woken_count.release() 25083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 25183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh # reacquire lock 25283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh for i in xrange(count): 25383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh self._lock.acquire() 25483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 25583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh def notify(self): 25683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh assert self._lock._semlock._is_mine(), 'lock is not owned' 25783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh assert not self._wait_semaphore.acquire(False) 25883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 25983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh # to take account of timeouts since last notify() we subtract 26083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh # woken_count from sleeping_count and rezero woken_count 26183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh while self._woken_count.acquire(False): 26283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh res = self._sleeping_count.acquire(False) 26383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh assert res 26483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 26583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh if self._sleeping_count.acquire(False): # try grabbing a sleeper 26683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh self._wait_semaphore.release() # wake up one sleeper 26783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh self._woken_count.acquire() # wait for the sleeper to wake 26883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 26983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh # rezero _wait_semaphore in case a timeout just happened 27083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh self._wait_semaphore.acquire(False) 27183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 27283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh def notify_all(self): 27383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh assert self._lock._semlock._is_mine(), 'lock is not owned' 27483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh assert not self._wait_semaphore.acquire(False) 27583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 27683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh # to take account of timeouts since last notify*() we subtract 27783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh # woken_count from sleeping_count and rezero woken_count 27883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh while self._woken_count.acquire(False): 27983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh res = self._sleeping_count.acquire(False) 28083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh assert res 28183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 28283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh sleepers = 0 28383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh while self._sleeping_count.acquire(False): 28483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh self._wait_semaphore.release() # wake up one sleeper 28583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh sleepers += 1 28683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 28783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh if sleepers: 28883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh for i in xrange(sleepers): 28983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh self._woken_count.acquire() # wait for a sleeper to wake 29083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 29183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh # rezero wait_semaphore in case some timeouts just happened 29283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh while self._wait_semaphore.acquire(False): 29383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh pass 29483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 29583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# 29683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# Event 29783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# 29883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 29983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehclass Event(object): 30083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 30183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh def __init__(self): 30283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh self._cond = Condition(Lock()) 30383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh self._flag = Semaphore(0) 30483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 30583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh def is_set(self): 30683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh self._cond.acquire() 30783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh try: 30883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh if self._flag.acquire(False): 30983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh self._flag.release() 31083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh return True 31183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh return False 31283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh finally: 31383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh self._cond.release() 31483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 31583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh def set(self): 31683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh self._cond.acquire() 31783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh try: 31883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh self._flag.acquire(False) 31983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh self._flag.release() 32083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh self._cond.notify_all() 32183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh finally: 32283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh self._cond.release() 32383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 32483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh def clear(self): 32583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh self._cond.acquire() 32683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh try: 32783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh self._flag.acquire(False) 32883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh finally: 32983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh self._cond.release() 33083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 33183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh def wait(self, timeout=None): 33283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh self._cond.acquire() 33383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh try: 33483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh if self._flag.acquire(False): 33583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh self._flag.release() 33683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh else: 33783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh self._cond.wait(timeout) 33883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 33983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh if self._flag.acquire(False): 34083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh self._flag.release() 34183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh return True 34283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh return False 34383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh finally: 34483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh self._cond.release() 345