def close(self): """Close this send channel object synchronously. All channel objects have an asynchronous `~.AsyncResource.aclose` method. Memory channels can also be closed synchronously. This has the same effect on the channel and other tasks using it, but `close` is not a trio checkpoint. This simplifies cleaning up in cancelled tasks. Using ``with send_channel:`` will close the channel object on leaving the with block. """ if self._closed: return self._closed = True for task in self._tasks: trio.lowlevel.reschedule(task, Error(trio.ClosedResourceError())) del self._state.send_tasks[task] self._tasks.clear() self._state.open_send_channels -= 1 if self._state.open_send_channels == 0: assert not self._state.send_tasks for task in self._state.receive_tasks: task.custom_sleep_data._tasks.remove(task) trio.lowlevel.reschedule(task, Error(trio.EndOfChannel())) self._state.receive_tasks.clear()
async def receive(self) -> Message: """Return the next available message from the connection""" while True: msg = self.parser.get_next_message() if msg is not None: return msg b = await self.socket.receive_some() if not b: raise trio.EndOfChannel("Socket closed at the other end") self.parser.add_data(b)
async def receive(self) -> Message: """Return the next available message from the connection""" async with self.recv_lock: while True: msg = self.parser.get_next_message() if msg is not None: return msg # Once data is read, it must be given to the parser with no # checkpoints (where the task could be cancelled). b, fds = await self._read_data() if not b: raise trio.EndOfChannel("Socket closed at the other end") self.parser.add_data(b, fds)
async def aclose(self): if self._closed: await trio.hazmat.checkpoint() return self._closed = True for task in self._tasks: trio.hazmat.reschedule(task, Error(trio.ClosedResourceError())) del self._state.send_tasks[task] self._tasks.clear() self._state.open_send_channels -= 1 if self._state.open_send_channels == 0: assert not self._state.send_tasks for task in self._state.receive_tasks: task.custom_sleep_data._tasks.remove(task) trio.hazmat.reschedule(task, Error(trio.EndOfChannel())) self._state.receive_tasks.clear() await trio.hazmat.checkpoint()