Index: tests/sys/aio/aio_test.c =================================================================== --- tests/sys/aio/aio_test.c +++ tests/sys/aio/aio_test.c @@ -201,7 +201,7 @@ * file descriptor. */ static void -aio_write_test(struct aio_context *ac) +aio_write_test(struct aio_context *ac, bool use_aio_suspend) { struct aiocb aio, *aiop; ssize_t len; @@ -227,16 +227,45 @@ atf_tc_fail("aio_write failed: %s", strerror(errno)); } - len = aio_waitcomplete(&aiop, NULL); - if (len < 0) { - if (errno == EINTR) { - if (aio_timedout) { + if (use_aio_suspend) { + const struct aiocb *const iocbs[] = {&aio}; + int err; + + err = aio_suspend(iocbs, 1, NULL); + if (err != 0) { + switch(errno) { + case EAGAIN: + case EINTR: aio_cleanup(ac); - atf_tc_fail("aio_waitcomplete timed out"); + atf_tc_fail("aio_suspend timed out"); + break; + default: + aio_cleanup(ac); + atf_tc_fail("aio_suspend returned unexpected " + "error: %s", strerror(errno)); + break; } } - aio_cleanup(ac); - atf_tc_fail("aio_waitcomplete failed: %s", strerror(errno)); + len = aio_return(&aio); + if (len < 0) { + aio_cleanup(ac); + atf_tc_fail("aio_write failed: %s", strerror(errno)); + } + + } else { + len = aio_waitcomplete(&aiop, NULL); + if (len < 0) { + if (errno == EINTR) { + if (aio_timedout) { + aio_cleanup(ac); + atf_tc_fail("aio_waitcomplete timed out" + ); + } + } + aio_cleanup(ac); + atf_tc_fail("aio_waitcomplete failed: %s", + strerror(errno)); + } } aio_timeout_stop(); @@ -353,7 +382,33 @@ aio_context_init(&ac, fd, fd, FILE_LEN, FILE_TIMEOUT, aio_file_cleanup, &arg); - aio_write_test(&ac); + aio_write_test(&ac, false); + aio_read_test(&ac); + + aio_file_cleanup(&arg); +} + +ATF_TC_WITHOUT_HEAD(aio_suspend_test); +ATF_TC_BODY(aio_suspend_test, tc) +{ + char pathname[PATH_MAX]; + struct aio_file_arg arg; + struct aio_context ac; + int fd; + + ATF_REQUIRE_KERNEL_MODULE("aio"); + ATF_REQUIRE_UNSAFE_AIO(); + + strcpy(pathname, PATH_TEMPLATE); + fd = mkstemp(pathname); + ATF_REQUIRE_MSG(fd != -1, "mkstemp failed: %s", strerror(errno)); + + arg.afa_fd = fd; + arg.afa_pathname = pathname; + + aio_context_init(&ac, fd, fd, FILE_LEN, + FILE_TIMEOUT, aio_file_cleanup, &arg); + aio_write_test(&ac, true); aio_read_test(&ac); aio_file_cleanup(&arg); @@ -429,7 +484,7 @@ aio_context_init(&ac, read_fd, write_fd, FIFO_LEN, FIFO_TIMEOUT, aio_fifo_cleanup, &arg); - aio_write_test(&ac); + aio_write_test(&ac, false); aio_read_test(&ac); aio_fifo_cleanup(&arg); @@ -471,7 +526,7 @@ aio_unix_socketpair_cleanup, &arg); ATF_REQUIRE_MSG(getrusage(RUSAGE_SELF, &ru_before) != -1, "getrusage failed: %s", strerror(errno)); - aio_write_test(&ac); + aio_write_test(&ac, false); ATF_REQUIRE_MSG(getrusage(RUSAGE_SELF, &ru_after) != -1, "getrusage failed: %s", strerror(errno)); ATF_REQUIRE(ru_after.ru_msgsnd == ru_before.ru_msgsnd + 1); @@ -535,7 +590,7 @@ aio_context_init(&ac, read_fd, write_fd, PTY_LEN, PTY_TIMEOUT, aio_pty_cleanup, &arg); - aio_write_test(&ac); + aio_write_test(&ac, false); aio_read_test(&ac); aio_pty_cleanup(&arg); @@ -566,7 +621,7 @@ aio_context_init(&ac, pipes[0], pipes[1], PIPE_LEN, PIPE_TIMEOUT, aio_pipe_cleanup, pipes); - aio_write_test(&ac); + aio_write_test(&ac, false); aio_read_test(&ac); aio_pipe_cleanup(pipes); @@ -654,7 +709,7 @@ aio_context_init(&ac, fd, fd, MD_LEN, MD_TIMEOUT, aio_md_cleanup, &arg); - aio_write_test(&ac); + aio_write_test(&ac, false); aio_read_test(&ac); aio_md_cleanup(&arg); @@ -1019,6 +1074,7 @@ ATF_TP_ADD_TC(tp, aio_socket_two_reads); ATF_TP_ADD_TC(tp, aio_socket_blocking_short_write); ATF_TP_ADD_TC(tp, aio_socket_short_write_cancel); + ATF_TP_ADD_TC(tp, aio_suspend_test); ATF_TP_ADD_TC(tp, aio_fsync_test); return (atf_no_error());