| 215 | # |
| 216 | |
| 217 | class Condition(object): |
| 218 | |
| 219 | def __init__(self, lock=None, *, ctx): |
| 220 | self._lock = lock or ctx.RLock() |
| 221 | self._sleeping_count = ctx.Semaphore(0) |
| 222 | self._woken_count = ctx.Semaphore(0) |
| 223 | self._wait_semaphore = ctx.Semaphore(0) |
| 224 | self._make_methods() |
| 225 | |
| 226 | def __getstate__(self): |
| 227 | context.assert_spawning(self) |
| 228 | return (self._lock, self._sleeping_count, |
| 229 | self._woken_count, self._wait_semaphore) |
| 230 | |
| 231 | def __setstate__(self, state): |
| 232 | (self._lock, self._sleeping_count, |
| 233 | self._woken_count, self._wait_semaphore) = state |
| 234 | self._make_methods() |
| 235 | |
| 236 | def __enter__(self): |
| 237 | return self._lock.__enter__() |
| 238 | |
| 239 | def __exit__(self, *args): |
| 240 | return self._lock.__exit__(*args) |
| 241 | |
| 242 | def _make_methods(self): |
| 243 | self.acquire = self._lock.acquire |
| 244 | self.release = self._lock.release |
| 245 | |
| 246 | def __repr__(self): |
| 247 | try: |
| 248 | num_waiters = (self._sleeping_count._semlock._get_value() - |
| 249 | self._woken_count._semlock._get_value()) |
| 250 | except Exception: |
| 251 | num_waiters = 'unknown' |
| 252 | return '<%s(%s, %s)>' % (self.__class__.__name__, self._lock, num_waiters) |
| 253 | |
| 254 | def wait(self, timeout=None): |
| 255 | assert self._lock._semlock._is_mine(), \ |
| 256 | 'must acquire() condition before using wait()' |
| 257 | |
| 258 | # indicate that this thread is going to sleep |
| 259 | self._sleeping_count.release() |
| 260 | |
| 261 | # release lock |
| 262 | count = self._lock._semlock._count() |
| 263 | for i in range(count): |
| 264 | self._lock.release() |
| 265 | |
| 266 | try: |
| 267 | # wait for notification or timeout |
| 268 | return self._wait_semaphore.acquire(True, timeout) |
| 269 | finally: |
| 270 | # indicate that this thread has woken |
| 271 | self._woken_count.release() |
| 272 | |
| 273 | # reacquire lock |
| 274 | for i in range(count): |