| 66 | |
| 67 | |
| 68 | class _ThreadWakeup: |
| 69 | def __init__(self): |
| 70 | self._closed = False |
| 71 | self._lock = threading.Lock() |
| 72 | self._reader, self._writer = mp.Pipe(duplex=False) |
| 73 | |
| 74 | def close(self): |
| 75 | # Please note that we do not take the self._lock when |
| 76 | # calling clear() (to avoid deadlocking) so this method can |
| 77 | # only be called safely from the same thread as all calls to |
| 78 | # clear() even if you hold the lock. Otherwise we |
| 79 | # might try to read from the closed pipe. |
| 80 | with self._lock: |
| 81 | if not self._closed: |
| 82 | self._closed = True |
| 83 | self._writer.close() |
| 84 | self._reader.close() |
| 85 | |
| 86 | def wakeup(self): |
| 87 | with self._lock: |
| 88 | if not self._closed: |
| 89 | self._writer.send_bytes(b"") |
| 90 | |
| 91 | def clear(self): |
| 92 | if self._closed: |
| 93 | raise RuntimeError('operation on closed _ThreadWakeup') |
| 94 | while self._reader.poll(): |
| 95 | self._reader.recv_bytes() |
| 96 | |
| 97 | |
| 98 | def _python_exit(): |
no outgoing calls
no test coverage detected
searching dependent graphs…