diff options
Diffstat (limited to 'test/poll-mshot-update.c')
-rw-r--r-- | test/poll-mshot-update.c | 78 |
1 files changed, 48 insertions, 30 deletions
diff --git a/test/poll-mshot-update.c b/test/poll-mshot-update.c index 1a9ea0a..caedb6f 100644 --- a/test/poll-mshot-update.c +++ b/test/poll-mshot-update.c @@ -9,7 +9,7 @@ #include <stdlib.h> #include <string.h> #include <signal.h> -#include <sys/poll.h> +#include <poll.h> #include <sys/resource.h> #include <fcntl.h> #include <pthread.h> @@ -28,7 +28,37 @@ struct p { }; static struct p p[NFILES]; -static int no_update; + +static int has_poll_update(void) +{ + struct io_uring ring; + struct io_uring_cqe *cqe; + struct io_uring_sqe *sqe; + bool has_update = false; + int ret; + + ret = io_uring_queue_init(8, &ring, 0); + if (ret) + return -1; + + sqe = io_uring_get_sqe(&ring); + io_uring_prep_poll_update(sqe, 0, 0, POLLIN, IORING_TIMEOUT_UPDATE); + + ret = io_uring_submit(&ring); + if (ret != 1) + return -1; + + ret = io_uring_wait_cqe(&ring, &cqe); + if (!ret) { + if (cqe->res == -ENOENT) + has_update = true; + else if (cqe->res != -EINVAL) + return -1; + io_uring_cqe_seen(&ring, cqe); + } + io_uring_queue_exit(&ring); + return has_update; +} static int arm_poll(struct io_uring *ring, int off) { @@ -40,8 +70,7 @@ static int arm_poll(struct io_uring *ring, int off) return 1; } - io_uring_prep_poll_add(sqe, p[off].fd[0], POLLIN); - sqe->len = 1; + io_uring_prep_poll_multishot(sqe, p[off].fd[0], POLLIN); sqe->user_data = off; return 0; } @@ -57,8 +86,8 @@ static int reap_polls(struct io_uring *ring) sqe = io_uring_get_sqe(ring); /* update event */ - io_uring_prep_poll_update(sqe, (void *)(unsigned long)i, NULL, - POLLIN, 2); + io_uring_prep_poll_update(sqe, i, 0, POLLIN, + IORING_POLL_UPDATE_EVENTS); sqe->user_data = 0x12345678; } @@ -77,7 +106,6 @@ static int reap_polls(struct io_uring *ring) off = cqe->user_data; if (off == 0x12345678) goto seen; - p[off].triggered = 0; ret = read(p[off].fd[0], &c, 1); if (ret != 1) { if (ret == -1 && errno == EAGAIN) @@ -128,19 +156,6 @@ static void *trigger_polls_fn(void *data) return NULL; } -static int check_no_update(struct io_uring *ring) -{ - struct io_uring_cqe *cqe; - int ret; - - ret = io_uring_wait_cqe(ring, &cqe); - if (ret) - return 0; - ret = cqe->res; - io_uring_cqe_seen(ring, cqe); - return ret == -EINVAL; -} - static int arm_polls(struct io_uring *ring) { int ret, to_arm = NFILES, i, off; @@ -163,10 +178,6 @@ static int arm_polls(struct io_uring *ring) ret = io_uring_submit(ring); if (ret != this_arm) { - if (ret > 0 && check_no_update(ring)) { - no_update = 1; - return 0; - } fprintf(stderr, "submitted %d, %d\n", ret, this_arm); return 1; } @@ -182,11 +193,20 @@ int main(int argc, char *argv[]) struct io_uring_params params = { }; struct rlimit rlim; pthread_t thread; - int i, ret; + int i, j, ret; if (argc > 1) return 0; + ret = has_poll_update(); + if (ret < 0) { + fprintf(stderr, "poll update check failed %i\n", ret); + return -1; + } else if (!ret) { + fprintf(stderr, "no poll update, skip\n"); + return 0; + } + if (getrlimit(RLIMIT_NOFILE, &rlim) < 0) { perror("getrlimit"); goto err_noring; @@ -227,10 +247,6 @@ int main(int argc, char *argv[]) if (arm_polls(&ring)) goto err; - if (no_update) { - printf("No poll update support, skipping\n"); - goto done; - } for (i = 0; i < NLOOPS; i++) { pthread_create(&thread, NULL, trigger_polls_fn, NULL); @@ -238,9 +254,11 @@ int main(int argc, char *argv[]) if (ret) goto err; pthread_join(thread, NULL); + + for (j = 0; j < NFILES; j++) + p[j].triggered = 0; } -done: io_uring_queue_exit(&ring); return 0; err: |