Example #1
0
    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()
Example #2
0
    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)
Example #3
0
    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)
Example #4
0
 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()