summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJens Axboe <axboe@kernel.dk>2022-05-16 20:37:59 -0600
committerJens Axboe <axboe@kernel.dk>2022-05-16 20:37:59 -0600
commit94d012715ab8425540f61a9ab5b66b21bc9e954e (patch)
tree343d2082e95394ef58af785e1bc2cb871798dea5
parentcd3f9fff5aa69a91bf412a36c444d8b1e048d439 (diff)
parent91040e8b1e22de8ec79161bba6ced308cdf6b8fd (diff)
downloadliburing-94d012715ab8425540f61a9ab5b66b21bc9e954e.tar.gz
liburing-94d012715ab8425540f61a9ab5b66b21bc9e954e.tar.bz2
Merge branch 'accept-multi'
* accept-multi: open/openat2: update man page to include IORING_FILE_INDEX_ALLOC liburing.h: use helper for io_uring_prep_multishot_accept() man/io_uring_prep_accept.3: fixup some phrasing man/io_uring_prep_accept.3: add man info for multishot accept test/accept.c: test for multishot direct accept with wrong arg test/accept.c: add test for multishot mode accept liburing.h: add api to support multishot accept direct liburing.h: support multishot accept test/accept.c: close the listen fd at the end of the test
-rw-r--r--man/io_uring_prep_accept.362
l---------man/io_uring_prep_multishot_accept.31
l---------man/io_uring_prep_multishot_accept_direct.31
-rw-r--r--man/io_uring_prep_openat.312
-rw-r--r--man/io_uring_prep_openat2.311
-rw-r--r--src/include/liburing.h20
-rw-r--r--src/include/liburing/io_uring.h14
-rw-r--r--test/accept.c326
8 files changed, 372 insertions, 75 deletions
diff --git a/man/io_uring_prep_accept.3 b/man/io_uring_prep_accept.3
index 779bcd9..bebc262 100644
--- a/man/io_uring_prep_accept.3
+++ b/man/io_uring_prep_accept.3
@@ -18,11 +18,23 @@ io_uring_prep_accept - prepare an accept request
.BI " int " flags ");"
.BI "
.BI "void io_uring_prep_accept_direct(struct io_uring_sqe *" sqe ","
-.BI " int " sockfd ","
-.BI " struct sockaddr *" addr ","
-.BI " socklen_t " addrlen ","
-.BI " int " flags ","
-.BI " unsigned int " file_index ");"
+.BI " int " sockfd ","
+.BI " struct sockaddr *" addr ","
+.BI " socklen_t " addrlen ","
+.BI " int " flags ","
+.BI " unsigned int " file_index ");"
+.BI "
+.BI "void io_uring_prep_multishot_accept(struct io_uring_sqe *" sqe ","
+.BI " int " sockfd ","
+.BI " struct sockaddr *" addr ","
+.BI " socklen_t " addrlen ","
+.BI " int " flags ");"
+.BI "
+.BI "void io_uring_prep_multishot_accept_direct(struct io_uring_sqe *" sqe ","
+.BI " int " sockfd ","
+.BI " struct sockaddr *" addr ","
+.BI " socklen_t " addrlen ","
+.BI " int " flags ");"
.PP
.SH DESCRIPTION
.PP
@@ -72,6 +84,36 @@ CQE
.I res
return.
+For a direct descriptor accept request, the
+.I file_index
+argument can be set to
+.B IORING_FILE_INDEX_ALLOC,
+In this case a free entry in io_uring file table will
+be used automatically and the file index will be returned as CQE
+.I res.
+.B -ENFILE
+is otherwise returned if there is no free entries in the io_uring file table.
+
+The multishot version accept and accept_direct allow an application to issue
+a single accept request, which will repeatedly trigger a CQE when a connection
+request comes in. Like other multishot type requests, the application should
+look at the CQE
+.I flags
+and see if
+.B IORING_CQE_F_MORE
+is set on completion as an indication of whether or not the accept request
+will generate further CQEs.
+
+For multishot with direct descriptors,
+.B IORING_FILE_INDEX_ALLOC
+must be used as the file descriptor. This tells io_uring to allocate a free
+direct descriptor from our table, rather than the application passing one in.
+Failure to do so will result in the accept request being terminated with
+.B -EINVAL.
+The allocated descriptor will be returned in the CQE
+.I res
+field, like a non-direct accept request.
+
This function prepares an async
.BR accept4 (2)
request. See that man page for details.
@@ -81,12 +123,14 @@ None
.SH ERRORS
The CQE
.I res
-field will contain the result of the operation. While the non-direct accept
-returns the installed file descriptor as its value, the direct accept
-returns
+field will contain the result of the operation. For singleshot accept, the
+non-direct accept returns the installed file descriptor as its value, the
+direct accept returns
.B 0
on success. The caller must know which direct descriptor was picked for this
-request. See the related man page for details on possible values for the
+request. For multishot accept, the non-direct accept returns the installed
+file descriptor as its value, the direct accept returns the file index used on
+success. See the related man page for details on possible values for the
non-direct accept. Note that where synchronous system calls will return
.B -1
on failure and set
diff --git a/man/io_uring_prep_multishot_accept.3 b/man/io_uring_prep_multishot_accept.3
new file mode 120000
index 0000000..0404bf5
--- /dev/null
+++ b/man/io_uring_prep_multishot_accept.3
@@ -0,0 +1 @@
+io_uring_prep_accept.3 \ No newline at end of file
diff --git a/man/io_uring_prep_multishot_accept_direct.3 b/man/io_uring_prep_multishot_accept_direct.3
new file mode 120000
index 0000000..0404bf5
--- /dev/null
+++ b/man/io_uring_prep_multishot_accept_direct.3
@@ -0,0 +1 @@
+io_uring_prep_accept.3 \ No newline at end of file
diff --git a/man/io_uring_prep_openat.3 b/man/io_uring_prep_openat.3
index 8094619..b0f0946 100644
--- a/man/io_uring_prep_openat.3
+++ b/man/io_uring_prep_openat.3
@@ -67,6 +67,18 @@ Note that old kernels don't check the SQE
field, which is not a problem for liburing helpers, but users of the raw
io_uring interface need to zero SQEs to avoid unexpected behavior.
+If
+.B IORING_FILE_INDEX_ALLOC
+is used as the
+.I file_index
+for a direct open, then io_uring will allocate a free direct descriptor in
+the existing table. The allocated descriptor is returned in the CQE
+.I res
+field just like it would be for a non-direct open request. If no more entries
+are available in the direct descriptor table,
+.B -ENFILE
+is returned instead.
+
This function prepares an async
.BR openat (2)
request. See that man page for details.
diff --git a/man/io_uring_prep_openat2.3 b/man/io_uring_prep_openat2.3
index 4898e30..96682d8 100644
--- a/man/io_uring_prep_openat2.3
+++ b/man/io_uring_prep_openat2.3
@@ -67,6 +67,17 @@ Note that old kernels don't check the SQE
.I file_index
field, which is not a problem for liburing helpers, but users of the raw
io_uring interface need to zero SQEs to avoid unexpected behavior.
+If
+.B IORING_FILE_INDEX_ALLOC
+is used as the
+.I file_index
+for a direct open, then io_uring will allocate a free direct descriptor in
+the existing table. The allocated descriptor is returned in the CQE
+.I res
+field just like it would be for a non-direct open request. If no more entries
+are available in the direct descriptor table,
+.B -ENFILE
+is returned instead.
This function prepares an async
.BR openat2 (2)
diff --git a/src/include/liburing.h b/src/include/liburing.h
index 1aedc35..4bdf0f6 100644
--- a/src/include/liburing.h
+++ b/src/include/liburing.h
@@ -514,6 +514,25 @@ static inline void io_uring_prep_accept_direct(struct io_uring_sqe *sqe, int fd,
__io_uring_set_target_fixed_file(sqe, file_index);
}
+static inline void io_uring_prep_multishot_accept(struct io_uring_sqe *sqe,
+ int fd, struct sockaddr *addr,
+ socklen_t *addrlen, int flags)
+{
+ io_uring_prep_accept(sqe, fd, addr, addrlen, flags);
+ sqe->ioprio |= IORING_ACCEPT_MULTISHOT;
+}
+
+/* multishot accept directly into the fixed file table */
+static inline void io_uring_prep_multishot_accept_direct(struct io_uring_sqe *sqe,
+ int fd,
+ struct sockaddr *addr,
+ socklen_t *addrlen,
+ int flags)
+{
+ io_uring_prep_multishot_accept(sqe, fd, addr, addrlen, flags);
+ __io_uring_set_target_fixed_file(sqe, IORING_FILE_INDEX_ALLOC - 1);
+}
+
static inline void io_uring_prep_cancel(struct io_uring_sqe *sqe,
__u64 user_data, int flags)
{
@@ -579,7 +598,6 @@ static inline void io_uring_prep_openat_direct(struct io_uring_sqe *sqe,
__io_uring_set_target_fixed_file(sqe, file_index);
}
-
static inline void io_uring_prep_close(struct io_uring_sqe *sqe, int fd)
{
io_uring_prep_rw(IORING_OP_CLOSE, sqe, fd, NULL, 0, 0);
diff --git a/src/include/liburing/io_uring.h b/src/include/liburing/io_uring.h
index 0acf05d..4d736d2 100644
--- a/src/include/liburing/io_uring.h
+++ b/src/include/liburing/io_uring.h
@@ -69,6 +69,15 @@ struct io_uring_sqe {
__u64 __pad2[1];
};
+/*
+ * If sqe->file_index is set to this for opcodes that instantiate a new
+ * direct descriptor (like openat/openat2/accept), then io_uring will allocate
+ * an available direct descriptor instead of having the application pass one
+ * in. The picked direct descriptor will be returned in cqe->res, or -ENFILE
+ * if the space is full.
+ */
+#define IORING_FILE_INDEX_ALLOC (~0U)
+
enum {
IOSQE_FIXED_FILE_BIT,
IOSQE_IO_DRAIN_BIT,
@@ -490,6 +499,11 @@ struct io_uring_getevents_arg {
__u64 ts;
};
+/*
+ * accept flags stored in sqe->ioprio
+ */
+#define IORING_ACCEPT_MULTISHOT (1U << 0)
+
#ifdef __cplusplus
}
#endif
diff --git a/test/accept.c b/test/accept.c
index c591e76..921c79b 100644
--- a/test/accept.c
+++ b/test/accept.c
@@ -7,6 +7,7 @@
#include <stdlib.h>
#include <stdint.h>
#include <assert.h>
+#include <limits.h>
#include <errno.h>
#include <fcntl.h>
@@ -22,6 +23,7 @@
#include "helpers.h"
#include "liburing.h"
+#define MAX_FDS 32
static int no_accept;
struct data {
@@ -29,6 +31,15 @@ struct data {
struct iovec iov;
};
+struct accept_test_args {
+ int accept_should_error;
+ bool fixed;
+ bool nonblock;
+ bool queue_accept_before_connect;
+ bool multishot;
+ int extra_loops;
+};
+
static void queue_send(struct io_uring *ring, int fd)
{
struct io_uring_sqe *sqe;
@@ -59,20 +70,32 @@ static void queue_recv(struct io_uring *ring, int fd, bool fixed)
sqe->flags |= IOSQE_FIXED_FILE;
}
-static void queue_accept_conn(struct io_uring *ring,
- int fd, int fixed_idx,
- int count)
+static void queue_accept_conn(struct io_uring *ring, int fd,
+ struct accept_test_args args)
{
struct io_uring_sqe *sqe;
int ret;
+ int fixed_idx = args.fixed ? 0 : -1;
+ int count = 1 + args.extra_loops;
+ bool multishot = args.multishot;
while (count--) {
sqe = io_uring_get_sqe(ring);
- if (fixed_idx < 0)
- io_uring_prep_accept(sqe, fd, NULL, NULL, 0);
- else
- io_uring_prep_accept_direct(sqe, fd, NULL, NULL, 0,
- fixed_idx);
+ if (fixed_idx < 0) {
+ if (!multishot)
+ io_uring_prep_accept(sqe, fd, NULL, NULL, 0);
+ else
+ io_uring_prep_multishot_accept(sqe, fd, NULL,
+ NULL, 0);
+ } else {
+ if (!multishot)
+ io_uring_prep_accept_direct(sqe, fd, NULL, NULL,
+ 0, fixed_idx);
+ else
+ io_uring_prep_multishot_accept_direct(sqe, fd,
+ NULL, NULL,
+ 0);
+ }
ret = io_uring_submit(ring);
assert(ret != -1);
@@ -131,71 +154,103 @@ static int start_accept_listen(struct sockaddr_in *addr, int port_off,
return fd;
}
-struct accept_test_args {
- int accept_should_error;
- bool fixed;
- bool nonblock;
- bool queue_accept_before_connect;
- int extra_loops;
-};
-
-
-static int test_loop(struct io_uring *ring,
- struct accept_test_args args,
- int recv_s0,
- struct sockaddr_in *addr)
+static int set_client_fd(struct sockaddr_in *addr)
{
- struct io_uring_cqe *cqe;
- uint32_t head, count = 0;
- int ret, p_fd[2], done = 0;
int32_t val;
+ int fd, ret;
- p_fd[1] = socket(AF_INET, SOCK_STREAM | SOCK_CLOEXEC, IPPROTO_TCP);
+ fd = socket(AF_INET, SOCK_STREAM | SOCK_CLOEXEC, IPPROTO_TCP);
val = 1;
- ret = setsockopt(p_fd[1], IPPROTO_TCP, TCP_NODELAY, &val, sizeof(val));
+ ret = setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &val, sizeof(val));
assert(ret != -1);
- int32_t flags = fcntl(p_fd[1], F_GETFL, 0);
+ int32_t flags = fcntl(fd, F_GETFL, 0);
assert(flags != -1);
flags |= O_NONBLOCK;
- ret = fcntl(p_fd[1], F_SETFL, flags);
+ ret = fcntl(fd, F_SETFL, flags);
assert(ret != -1);
- ret = connect(p_fd[1], (struct sockaddr *)addr, sizeof(*addr));
+ ret = connect(fd, (struct sockaddr *)addr, sizeof(*addr));
assert(ret == -1);
- flags = fcntl(p_fd[1], F_GETFL, 0);
+ flags = fcntl(fd, F_GETFL, 0);
assert(flags != -1);
flags &= ~O_NONBLOCK;
- ret = fcntl(p_fd[1], F_SETFL, flags);
+ ret = fcntl(fd, F_SETFL, flags);
assert(ret != -1);
- if (!args.queue_accept_before_connect)
- queue_accept_conn(ring, recv_s0, args.fixed ? 0 : -1, 1);
+ return fd;
+}
- p_fd[0] = accept_conn(ring, args.fixed ? 0 : -1);
- if (p_fd[0] == -EINVAL) {
- if (args.accept_should_error)
+static int test_loop(struct io_uring *ring,
+ struct accept_test_args args,
+ int recv_s0,
+ struct sockaddr_in *addr)
+{
+ struct io_uring_cqe *cqe;
+ uint32_t head, count = 0;
+ int i, ret, s_fd[MAX_FDS], c_fd[MAX_FDS], done = 0;
+ bool fixed = args.fixed;
+ bool multishot = args.multishot;
+ unsigned int multishot_mask = 0;
+
+ for (i = 0; i < MAX_FDS; i++) {
+ c_fd[i] = set_client_fd(addr);
+ if (!multishot)
+ break;
+ }
+
+ if (!args.queue_accept_before_connect)
+ queue_accept_conn(ring, recv_s0, args);
+
+ for (i = 0; i < MAX_FDS; i++) {
+ s_fd[i] = accept_conn(ring, args.fixed ? 0 : -1);
+ if (s_fd[i] == -EINVAL) {
+ if (args.accept_should_error)
+ goto out;
+ fprintf(stdout,
+ "%s %s Accept not supported, skipping\n",
+ fixed ? "Fixed" : "",
+ multishot ? "Multishot" : "");
+ no_accept = 1;
goto out;
- if (args.fixed)
- fprintf(stdout, "Fixed accept not supported, skipping\n");
- else
- fprintf(stdout, "Accept not supported, skipping\n");
- no_accept = 1;
+ } else if (s_fd[i] < 0) {
+ if (args.accept_should_error &&
+ (s_fd[i] == -EBADF || s_fd[i] == -EINVAL))
+ goto out;
+ fprintf(stderr, "%s %s Accept[%d] got %d\n",
+ fixed ? "Fixed" : "",
+ multishot ? "Multishot" : "",
+ i, s_fd[i]);
+ goto err;
+ }
+
+ if (multishot && fixed) {
+ if (s_fd[i] >= MAX_FDS) {
+ fprintf(stderr,
+ "Fixed Multishot Accept[%d] got outbound index: %d\n",
+ i, s_fd[i]);
+ goto err;
+ }
+ multishot_mask |= (1 << (s_fd[i] - 1));
+ }
+ if (!multishot)
+ break;
+ }
+
+ if (multishot) {
+ if (fixed && multishot_mask != UINT_MAX) {
+ fprintf(stderr, "Fixed Multishot Accept misses events\n");
+ goto err;
+ }
goto out;
- } else if (p_fd[0] < 0) {
- if (args.accept_should_error &&
- (p_fd[0] == -EBADF || p_fd[0] == -EINVAL))
- goto out;
- fprintf(stderr, "Accept got %d\n", p_fd[0]);
- goto err;
}
- queue_send(ring, p_fd[1]);
- queue_recv(ring, p_fd[0], args.fixed);
+ queue_send(ring, c_fd[0]);
+ queue_recv(ring, s_fd[0], args.fixed);
ret = io_uring_submit_and_wait(ring, 2);
assert(ret != -1);
@@ -219,14 +274,32 @@ static int test_loop(struct io_uring *ring,
}
out:
- if (!args.fixed)
- close(p_fd[0]);
- close(p_fd[1]);
+ if (!args.fixed) {
+ for (i = 0; i < MAX_FDS; i++) {
+ close(s_fd[i]);
+ if (!multishot)
+ break;
+ }
+ }
+ for (i = 0; i < MAX_FDS; i++) {
+ close(c_fd[i]);
+ if (!multishot)
+ break;
+ }
return 0;
err:
- if (!args.fixed)
- close(p_fd[0]);
- close(p_fd[1]);
+ if (!args.fixed) {
+ for (i = 0; i < MAX_FDS; i++) {
+ close(s_fd[i]);
+ if (!multishot)
+ break;
+ }
+ }
+ for (i = 0; i < MAX_FDS; i++) {
+ close(c_fd[i]);
+ if (!multishot)
+ break;
+ }
return 1;
}
@@ -238,8 +311,7 @@ static int test(struct io_uring *ring, struct accept_test_args args)
int32_t recv_s0 = start_accept_listen(&addr, 0,
args.nonblock ? O_NONBLOCK : 0);
if (args.queue_accept_before_connect)
- queue_accept_conn(ring, recv_s0, args.fixed ? 0 : -1,
- 1 + args.extra_loops);
+ queue_accept_conn(ring, recv_s0, args);
for (loop = 0; loop < 1 + args.extra_loops; loop++) {
ret = test_loop(ring, args, recv_s0, &addr);
if (ret)
@@ -364,7 +436,7 @@ out:
return ret;
}
-static int test_accept_cancel(unsigned usecs, unsigned int nr)
+static int test_accept_cancel(unsigned usecs, unsigned int nr, bool multishot)
{
struct io_uring m_io_uring;
struct io_uring_cqe *cqe;
@@ -378,7 +450,10 @@ static int test_accept_cancel(unsigned usecs, unsigned int nr)
for (i = 1; i <= nr; i++) {
sqe = io_uring_get_sqe(&m_io_uring);
- io_uring_prep_accept(sqe, fd, NULL, NULL, 0);
+ if (!multishot)
+ io_uring_prep_accept(sqe, fd, NULL, NULL, 0);
+ else
+ io_uring_prep_multishot_accept(sqe, fd, NULL, NULL, 0);
sqe->user_data = i;
ret = io_uring_submit(&m_io_uring);
assert(ret == 1);
@@ -425,9 +500,11 @@ static int test_accept_cancel(unsigned usecs, unsigned int nr)
}
io_uring_queue_exit(&m_io_uring);
+ close(fd);
return 0;
err:
io_uring_queue_exit(&m_io_uring);
+ close(fd);
return 1;
}
@@ -447,6 +524,60 @@ static int test_accept(int count, bool before)
return ret;
}
+static int test_multishot_accept(int count, bool before)
+{
+ struct io_uring m_io_uring;
+ int ret;
+ struct accept_test_args args = {
+ .queue_accept_before_connect = before,
+ .multishot = true,
+ .extra_loops = count - 1
+ };
+
+ ret = io_uring_queue_init(MAX_FDS + 10, &m_io_uring, 0);
+ assert(ret >= 0);
+ ret = test(&m_io_uring, args);
+ io_uring_queue_exit(&m_io_uring);
+ return ret;
+}
+
+static int test_accept_multishot_wrong_arg()
+{
+ struct io_uring m_io_uring;
+ struct io_uring_cqe *cqe;
+ struct io_uring_sqe *sqe;
+ int fd, ret;
+
+ ret = io_uring_queue_init(4, &m_io_uring, 0);
+ assert(ret >= 0);
+
+ fd = start_accept_listen(NULL, 0, 0);
+
+ sqe = io_uring_get_sqe(&m_io_uring);
+ io_uring_prep_multishot_accept_direct(sqe, fd, NULL, NULL, 0);
+ sqe->file_index = 1;
+ ret = io_uring_submit(&m_io_uring);
+ assert(ret == 1);
+
+ ret = io_uring_wait_cqe(&m_io_uring, &cqe);
+ assert(!ret);
+ if (cqe->res != -EINVAL) {
+ fprintf(stderr, "file index should be IORING_FILE_INDEX_ALLOC \
+ if its accept in multishot direct mode\n");
+ goto err;
+ }
+ io_uring_cqe_seen(&m_io_uring, cqe);
+
+ io_uring_queue_exit(&m_io_uring);
+ close(fd);
+ return 0;
+err:
+ io_uring_queue_exit(&m_io_uring);
+ close(fd);
+ return 1;
+}
+
+
static int test_accept_nonblock(bool queue_before_connect, int count)
{
struct io_uring m_io_uring;
@@ -481,6 +612,25 @@ static int test_accept_fixed(void)
return ret;
}
+static int test_multishot_fixed_accept(void)
+{
+ struct io_uring m_io_uring;
+ int ret, fd[100];
+ struct accept_test_args args = {
+ .fixed = true,
+ .multishot = true
+ };
+
+ memset(fd, -1, sizeof(fd));
+ ret = io_uring_queue_init(MAX_FDS + 10, &m_io_uring, 0);
+ assert(ret >= 0);
+ ret = io_uring_register_files(&m_io_uring, fd, MAX_FDS);
+ assert(ret == 0);
+ ret = test(&m_io_uring, args);
+ io_uring_queue_exit(&m_io_uring);
+ return ret;
+}
+
static int test_accept_sqpoll(void)
{
struct io_uring m_io_uring;
@@ -510,7 +660,6 @@ int main(int argc, char *argv[])
if (argc > 1)
return 0;
-
ret = test_accept(1, false);
if (ret) {
fprintf(stderr, "test_accept failed\n");
@@ -555,36 +704,84 @@ int main(int argc, char *argv[])
return ret;
}
+ ret = test_multishot_fixed_accept();
+ if (ret) {
+ fprintf(stderr, "test_multishot_fixed_accept failed\n");
+ return ret;
+ }
+
+ ret = test_accept_multishot_wrong_arg();
+ if (ret) {
+ fprintf(stderr, "test_accept_multishot_wrong_arg failed\n");
+ return ret;
+ }
+
ret = test_accept_sqpoll();
if (ret) {
fprintf(stderr, "test_accept_sqpoll failed\n");
return ret;
}
- ret = test_accept_cancel(0, 1);
+ ret = test_accept_cancel(0, 1, false);
if (ret) {
fprintf(stderr, "test_accept_cancel nodelay failed\n");
return ret;
}
- ret = test_accept_cancel(10000, 1);
+ ret = test_accept_cancel(10000, 1, false);
if (ret) {
fprintf(stderr, "test_accept_cancel delay failed\n");
return ret;
}
- ret = test_accept_cancel(0, 4);
+ ret = test_accept_cancel(0, 4, false);
if (ret) {
fprintf(stderr, "test_accept_cancel nodelay failed\n");
return ret;
}
- ret = test_accept_cancel(10000, 4);
+ ret = test_accept_cancel(10000, 4, false);
if (ret) {
fprintf(stderr, "test_accept_cancel delay failed\n");
return ret;
}
+ ret = test_accept_cancel(0, 1, true);
+ if (ret) {
+ fprintf(stderr, "test_accept_cancel multishot nodelay failed\n");
+ return ret;
+ }
+
+ ret = test_accept_cancel(10000, 1, true);
+ if (ret) {
+ fprintf(stderr, "test_accept_cancel multishot delay failed\n");
+ return ret;
+ }
+
+ ret = test_accept_cancel(0, 4, true);
+ if (ret) {
+ fprintf(stderr, "test_accept_cancel multishot nodelay failed\n");
+ return ret;
+ }
+
+ ret = test_accept_cancel(10000, 4, true);
+ if (ret) {
+ fprintf(stderr, "test_accept_cancel multishot delay failed\n");
+ return ret;
+ }
+
+ ret = test_multishot_accept(1, false);
+ if (ret) {
+ fprintf(stderr, "test_multishot_accept(1, false) failed\n");
+ return ret;
+ }
+
+ ret = test_multishot_accept(1, true);
+ if (ret) {
+ fprintf(stderr, "test_multishot_accept(1, true) failed\n");
+ return ret;
+ }
+
ret = test_accept_many((struct test_accept_many_args) {});
if (ret) {
fprintf(stderr, "test_accept_many failed\n");
@@ -619,6 +816,5 @@ int main(int argc, char *argv[])
fprintf(stderr, "test_accept_pending_on_exit failed\n");
return ret;
}
-
return 0;
}