Example #1
0
    def _channel_read(self, channel, nbytes, read_func=None):
        if read_func is None:
            read_func = lambda channel, nbytes: channel.read(nbytes)

        source = GLib.io_create_watch(channel, GLib.IO_IN | GLib.IO_HUP)

        def channel_readable(read_func, channel, nbytes):
            return (True, read_func(channel, nbytes))
        return self._delayed(source, channel_readable, read_func, channel, nbytes)
Example #2
0
    def _channel_read(self, channel, nbytes, read_func=None):
        if read_func is None:
            read_func = lambda channel, nbytes: channel.read(nbytes)

        source = GLib.io_create_watch(channel, GLib.IO_IN | GLib.IO_HUP)

        def channel_readable(read_func, channel, nbytes):
            return (True, read_func(channel, nbytes))
        return self._delayed(source, channel_readable, read_func, channel, nbytes)
Example #3
0
    def add_writer(self, fileobj, callback, *args):
        fd = self._fileobj_to_fd(fileobj)
        self._ensure_fd_no_transport(fd)

        self.remove_writer(fd)
        channel = self._channel_from_socket(fd)
        source = GLib.io_create_watch(channel,
                                      GLib.IO_OUT | GLib.IO_ERR | GLib.IO_NVAL)

        assert fd not in self._writers
        self._writers[fd] = GLibHandle(loop=self,
                                       source=source,
                                       repeat=True,
                                       callback=callback,
                                       args=args)
Example #4
0
    def add_writer(self, fileobj, callback, *args):
        fd = self._fileobj_to_fd(fileobj)
        self._ensure_fd_no_transport(fd)

        self.remove_writer(fd)
        channel = self._channel_from_socket(fd)
        source = GLib.io_create_watch(channel, GLib.IO_OUT | GLib.IO_ERR | GLib.IO_NVAL)

        assert fd not in self._writers
        self._writers[fd] = GLibHandle(
            loop=self,
            source=source,
            repeat=True,
            callback=callback,
            args=args)
Example #5
0
    def sock_connect(self, sock, address):
        # Request connection on socket (it is expected that `sock` is already non-blocking)
        try:
            sock.connect(address)
        except BlockingIOError:
            pass

        # Create glib IOChannel for socket and wait for it to become writable
        channel = self._channel_from_socket(sock)
        source = GLib.io_create_watch(channel, GLib.IO_OUT)

        def sock_finish_connect(sock):
            self._socket_handle_errors(sock)
            return (True, sock)
        return self._delayed(source, sock_finish_connect, sock)
Example #6
0
    def sock_connect(self, sock, address):
        # Request connection on socket (it is expected that `sock` is already non-blocking)
        try:
            sock.connect(address)
        except BlockingIOError:
            pass

        # Create glib IOChannel for socket and wait for it to become writable
        channel = self._channel_from_socket(sock)
        source = GLib.io_create_watch(channel, GLib.IO_OUT)

        def sock_finish_connect(sock):
            self._socket_handle_errors(sock)
            return (True, sock)
        return self._delayed(source, sock_finish_connect, sock)
Example #7
0
    def sock_accept(self, sock):
        channel = self._channel_from_socket(sock)
        source = GLib.io_create_watch(channel, GLib.IO_IN)

        def sock_connection_received(sock):
            return (True, sock.accept())

        async def accept_coro(future, conn):
            # Coroutine closing the accept socket if the future is cancelled
            try:
                return (await future)
            except CancelledError:
                sock.close()
                raise

        future = self._delayed(source, sock_connection_received, sock)
        return self.create_task(accept_coro(future, sock))
Example #8
0
    def sock_accept(self, sock):
        channel = self._channel_from_socket(sock)
        source = GLib.io_create_watch(channel, GLib.IO_IN)

        def sock_connection_received(sock):
            return (True, sock.accept())

        @asyncio.coroutine
        def accept_coro(future, conn):
            # Coroutine closing the accept socket if the future is cancelled
            try:
                return (yield from future)
            except futures.CancelledError:
                sock.close()
                raise

        future = self._delayed(source, sock_connection_received, sock)
        return self.create_task(accept_coro(future, sock))
Example #9
0
    def _channel_write(self, channel, buf, write_func=None):
        if write_func is None:
            # note: channel.write doesn't raise BlockingIOError, instead it
            # returns 0
            # gi.overrides.GLib.write has an isinstance(buf, bytes) check, so
            # we can't give it a bytearray or a memoryview.
            def write_func(channel, buf):
                return channel.write(bytes(buf))

        buflen = len(buf)

        # Fast-path: If there is enough room in the OS buffer all data can be written synchronously
        try:
            nbytes = write_func(channel, buf)
        except BlockingIOError:
            nbytes = 0
        else:
            if nbytes >= len(buf):
                # All data was written synchronously in one go
                result = asyncio.Future(loop=self)
                result.set_result(nbytes)
                return result

        # Chop off the initially transmitted data and store result
        # as a bytearray for easier future modification
        buf = bytearray(buf[nbytes:])

        # Send the remaining data asynchronously as the socket becomes writable
        source = GLib.io_create_watch(channel, GLib.IO_OUT)

        def channel_writable(buflen, write_func, channel, buf):
            nbytes = write_func(channel, buf)
            if nbytes >= len(buf):
                return (True, buflen)
            else:
                del buf[0:nbytes]
                return (False, buflen)

        return self._delayed(source, channel_writable, buflen, write_func,
                             channel, buf)
Example #10
0
    def _channel_write(self, channel, buf, write_func=None):
        if write_func is None:
            # note: channel.write doesn't raise BlockingIOError, instead it
            # returns 0
            # gi.overrides.GLib.write has an isinstance(buf, bytes) check, so
            # we can't give it a bytearray or a memoryview.
            write_func = lambda channel, buf: channel.write(bytes(buf))
        buflen = len(buf)

        # Fast-path: If there is enough room in the OS buffer all data can be written synchronously
        try:
            nbytes = write_func(channel, buf)
        except BlockingIOError:
            nbytes = 0
        else:
            if nbytes >= len(buf):
                # All data was written synchronously in one go
                result = asyncio.Future(loop=self)
                result.set_result(nbytes)
                return result

        # Chop off the initially transmitted data and store result
        # as a bytearray for easier future modification
        buf = bytearray(buf[nbytes:])

        # Send the remaining data asynchronously as the socket becomes writable
        source = GLib.io_create_watch(channel, GLib.IO_OUT)

        def channel_writable(buflen, write_func, channel, buf):
            nbytes = write_func(channel, buf)
            if nbytes >= len(buf):
                return (True, buflen)
            else:
                del buf[0:nbytes]
                return (False, buflen)
        return self._delayed(source, channel_writable, buflen, write_func, channel, buf)