The receiving end of a cross-interpreter channel.
| 125 | |
| 126 | |
| 127 | class RecvChannel(_ChannelEnd): |
| 128 | """The receiving end of a cross-interpreter channel.""" |
| 129 | |
| 130 | _end = 'recv' |
| 131 | |
| 132 | def recv(self, timeout=None, *, |
| 133 | _sentinel=object(), |
| 134 | _delay=10 / 1000, # 10 milliseconds |
| 135 | ): |
| 136 | """Return the next object from the channel. |
| 137 | |
| 138 | This blocks until an object has been sent, if none have been |
| 139 | sent already. |
| 140 | """ |
| 141 | if timeout is not None: |
| 142 | timeout = int(timeout) |
| 143 | if timeout < 0: |
| 144 | raise ValueError(f'timeout value must be non-negative') |
| 145 | end = time.time() + timeout |
| 146 | obj, unboundop = _channels.recv(self._id, _sentinel) |
| 147 | while obj is _sentinel: |
| 148 | time.sleep(_delay) |
| 149 | if timeout is not None and time.time() >= end: |
| 150 | raise TimeoutError |
| 151 | obj, unboundop = _channels.recv(self._id, _sentinel) |
| 152 | if unboundop is not None: |
| 153 | assert obj is None, repr(obj) |
| 154 | return _resolve_unbound(unboundop) |
| 155 | return obj |
| 156 | |
| 157 | def recv_nowait(self, default=_NOT_SET): |
| 158 | """Return the next object from the channel. |
| 159 | |
| 160 | If none have been sent then return the default if one |
| 161 | is provided or fail with ChannelEmptyError. Otherwise this |
| 162 | is the same as recv(). |
| 163 | """ |
| 164 | if default is _NOT_SET: |
| 165 | obj, unboundop = _channels.recv(self._id) |
| 166 | else: |
| 167 | obj, unboundop = _channels.recv(self._id, default) |
| 168 | if unboundop is not None: |
| 169 | assert obj is None, repr(obj) |
| 170 | return _resolve_unbound(unboundop) |
| 171 | return obj |
| 172 | |
| 173 | def close(self): |
| 174 | _channels.close(self._id, recv=True) |
| 175 | |
| 176 | |
| 177 | class SendChannel(_ChannelEnd): |