Ejemplo n.º 1
0
def onwait_flag(path):

    fd = os.open(path, os.O_RDWR | os.O_CREAT | os.O_NONBLOCK, 0o660)

    one = bytearray(6)
    two = bytearray(5)
    vec = liburing.iovec(one, two)

    ring = liburing.io_uring()
    cqes = liburing.io_uring_cqes()

    # print()

    try:
        # WRITE
        # -----
        os.write(fd, b'hello world')
        os.fsync(fd)

        assert liburing.io_uring_queue_init(2, ring, 0) == 0

        # READ
        # ----
        sqe = liburing.io_uring_get_sqe(ring)
        liburing.io_uring_prep_readv(sqe, fd, vec, len(vec), 0, os.RWF_NOWAIT)
        sqe.user_data = 1

        assert liburing.io_uring_submit(ring) == 1

        while True:
            try:
                liburing.io_uring_peek_cqe(ring, cqes)
            except BlockingIOError:
                pass  # print('test_rwf_nowait_flag BlockingIOError', flush=True)
            else:
                cqe = cqes[0]
                liburing.trap_error(cqe.res)
                assert cqe.res == 6 + 5
                assert cqe.user_data == 1
                assert one == b'hello '
                assert two == b'world'
                liburing.io_uring_cqe_seen(ring, cqe)
                break
    finally:
        liburing.io_uring_queue_exit(ring)
        os.close(fd)
        os.unlink(path)
Ejemplo n.º 2
0
def test_socket_timeout():
    ring = liburing.io_uring()
    cqes = liburing.io_uring_cqes()

    # socket
    server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)
    server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, True)
    server.bind(('0.0.0.0', 0))  # random port
    server.listen(32)

    # prepare
    fd = server.fileno()
    addr, addrlen = liburing.sockaddr()
    try:
        # initialization
        assert liburing.io_uring_queue_init(32, ring, 0) == 0

        # accept
        sqe = liburing.io_uring_get_sqe(ring)
        liburing.io_uring_prep_accept(sqe, fd, addr, addrlen, 0)
        sqe.flags |= liburing.IOSQE_IO_LINK
        sqe.user_data = 1

        sqe = liburing.io_uring_get_sqe(ring)
        ts = liburing.timespec(0, 41666)  # 1000000//24 nanosecond
        liburing.io_uring_prep_link_timeout(sqe, ts, 0)
        sqe.user_data = 2

        assert liburing.io_uring_submit(ring) == 2

        while True:
            try:
                assert liburing.io_uring_peek_cqe(ring, cqes) == 0
            except BlockingIOError:
                pass  # waiting for events, do something else here.
            else:
                cqe = cqes[0]
                if cqe.user_data == 1:
                    # OSError: [Errno 125] Operation canceled
                    assert cqe.res == -125
                    liburing.io_uring_cqe_seen(ring, cqe)
                    continue
                else:
                    # Timeout value confirm
                    assert cqe.user_data == 2

                    # `OSError: [Errno 62] Timer expired` or
                    # `BlockingIOError: [Errno 114] Operation already in progress`
                    assert cqe.res in (-62, -114)
                    liburing.io_uring_cqe_seen(ring, cqe)
                    break

    finally:
        server.close()
        liburing.io_uring_queue_exit(ring)
Ejemplo n.º 3
0
def onwait_flag_empty_file(path, flag):

    fd = os.open(path, os.O_RDWR | os.O_CREAT | os.O_NONBLOCK, 0o660)
    read = bytearray(5)
    vec = liburing.iovec(read)

    ring = liburing.io_uring()
    cqes = liburing.io_uring_cqes()

    try:
        assert liburing.io_uring_queue_init(2, ring, 0) == 0

        # READ empty file
        # ---------------
        sqe = liburing.io_uring_get_sqe(ring)
        liburing.io_uring_prep_readv(sqe, fd, vec, len(vec), 0, flag)
        sqe.user_data = 1

        assert liburing.io_uring_submit(ring) == 1

        while True:
            try:
                liburing.io_uring_peek_cqe(ring, cqes)
            except BlockingIOError:
                pass  # print('test_rwf_nowait_flag BlockingIOError', flush=True)
            else:
                cqe = cqes[0]
                # empty file with `RWF_NOWAIT` flag will return `-EAGAIN` rather then `0`
                if flag & os.RWF_NOWAIT:
                    assert cqe.res == -errno.EAGAIN
                else:
                    assert cqe.res == 0
                liburing.io_uring_cqe_seen(ring, cqe)
                break
    finally:
        liburing.io_uring_queue_exit(ring)
        os.close(fd)
        os.unlink(path)
Ejemplo n.º 4
0
def test_event(tmpdir):
    fd = os.open(os.path.join(tmpdir, 'event.txt'), os.O_RDWR | os.O_CREAT,
                 0o660)
    ring = liburing.io_uring()
    cqes = liburing.io_uring_cqes()

    # prepare for writing.
    data = bytearray(b'hello world')
    vecs = liburing.iovec(data)

    try:
        # initialization
        assert liburing.io_uring_queue_init(32, ring, 0) == 0

        sqe = liburing.io_uring_get_sqe(ring)
        liburing.io_uring_prep_writev(sqe, fd, vecs, len(vecs), 0)
        assert liburing.io_uring_submit(ring) == 1

        while True:
            try:
                liburing.io_uring_peek_cqe(ring, cqes)
            except BlockingIOError:
                pass  # waiting for events, do something else here.
            else:
                cqe = cqes[0]
                assert cqe.res == 11
                liburing.io_uring_cqe_seen(ring, cqe)
                break

        # confirm
        content = os.read(fd, 100)
        assert content == data
        assert len(content) == vecs[0].iov_len
    finally:
        os.close(fd)
        liburing.io_uring_queue_exit(ring)
Ejemplo n.º 5
0
    def eventfd_callback(self):
        libc.eventfd_read(self.event_fd, os.O_NONBLOCK | os.O_CLOEXEC)
        while True:
            try:
                liburing.io_uring_peek_cqe(self.ring, self.cqes)
            except BlockingIOError:
                break
            cqe = self.cqes[0]
            result = liburing.trap_error(cqe.res)
            request_type, future, *args = self.store[cqe.user_data]

            if request_type is RequestType.OPEN:
                future.set_result(result)
            elif request_type is RequestType.CLOSE:
                future.set_result(None)
            elif request_type is RequestType.READ:
                future.set_result(args[0])
            elif request_type is RequestType.WRITE:
                future.set_result(None)
            else:
                raise RuntimeError

            del self.store[cqe.user_data]
            liburing.io_uring_cqe_seen(self.ring, cqe)