diff options
author | gjb <gjb@FreeBSD.org> | 2016-04-16 02:32:12 +0000 |
---|---|---|
committer | gjb <gjb@FreeBSD.org> | 2016-04-16 02:32:12 +0000 |
commit | 6549ef7d128d37c0dfff87f6c1c189b42ed3e1ef (patch) | |
tree | a8871301d693c6d33d43cd3171b1ee4783fec0e4 /tests | |
parent | ae096a53a90aee9859587d48d5a0279567abb413 (diff) | |
parent | 35691f7a6f04cec368d8636543bca596e870faf3 (diff) | |
download | FreeBSD-src-6549ef7d128d37c0dfff87f6c1c189b42ed3e1ef.zip FreeBSD-src-6549ef7d128d37c0dfff87f6c1c189b42ed3e1ef.tar.gz |
MFH
Sponsored by: The FreeBSD Foundation
Diffstat (limited to 'tests')
-rw-r--r-- | tests/sys/aio/aio_test.c | 60 | ||||
-rw-r--r-- | tests/sys/file/flock_helper.c | 2 |
2 files changed, 61 insertions, 1 deletions
diff --git a/tests/sys/aio/aio_test.c b/tests/sys/aio/aio_test.c index 5515161..1b10088 100644 --- a/tests/sys/aio/aio_test.c +++ b/tests/sys/aio/aio_test.c @@ -722,6 +722,65 @@ finished: close(fd); } +/* + * This tests for a bug where arriving socket data can wakeup multiple + * AIO read requests resulting in an uncancellable request. + */ +ATF_TC_WITHOUT_HEAD(aio_socket_two_reads); +ATF_TC_BODY(aio_socket_two_reads, tc) +{ + struct ioreq { + struct aiocb iocb; + char buffer[1024]; + } ioreq[2]; + struct aiocb *iocb; + unsigned i; + int s[2]; + char c; + + ATF_REQUIRE_KERNEL_MODULE("aio"); +#if __FreeBSD_version < 1100101 + aft_tc_skip("kernel version %d is too old (%d required)", + __FreeBSD_version, 1100101); +#endif + + ATF_REQUIRE(socketpair(PF_UNIX, SOCK_STREAM, 0, s) != -1); + + /* Queue two read requests. */ + memset(&ioreq, 0, sizeof(ioreq)); + for (i = 0; i < nitems(ioreq); i++) { + ioreq[i].iocb.aio_nbytes = sizeof(ioreq[i].buffer); + ioreq[i].iocb.aio_fildes = s[0]; + ioreq[i].iocb.aio_buf = ioreq[i].buffer; + ATF_REQUIRE(aio_read(&ioreq[i].iocb) == 0); + } + + /* Send a single byte. This should complete one request. */ + c = 0xc3; + ATF_REQUIRE(write(s[1], &c, sizeof(c)) == 1); + + ATF_REQUIRE(aio_waitcomplete(&iocb, NULL) == 1); + + /* Determine which request completed and verify the data was read. */ + if (iocb == &ioreq[0].iocb) + i = 0; + else + i = 1; + ATF_REQUIRE(ioreq[i].buffer[0] == c); + + i ^= 1; + + /* + * Try to cancel the other request. On broken systems this + * will fail and the process will hang on exit. + */ + ATF_REQUIRE(aio_error(&ioreq[i].iocb) == EINPROGRESS); + ATF_REQUIRE(aio_cancel(s[0], &ioreq[i].iocb) == AIO_CANCELED); + + close(s[1]); + close(s[0]); +} + ATF_TP_ADD_TCS(tp) { @@ -732,6 +791,7 @@ ATF_TP_ADD_TCS(tp) ATF_TP_ADD_TC(tp, aio_pipe_test); ATF_TP_ADD_TC(tp, aio_md_test); ATF_TP_ADD_TC(tp, aio_large_read_test); + ATF_TP_ADD_TC(tp, aio_socket_two_reads); return (atf_no_error()); } diff --git a/tests/sys/file/flock_helper.c b/tests/sys/file/flock_helper.c index 49e47b8..0fca15e 100644 --- a/tests/sys/file/flock_helper.c +++ b/tests/sys/file/flock_helper.c @@ -1566,7 +1566,7 @@ main(int argc, const char *argv[]) } else { testnum = 0; test_argc = 0; - test_argv = 0; + test_argv = NULL; } sa.sa_handler = ignore_alarm; |