Changeset View
Changeset View
Standalone View
Standalone View
tests/sys/aio/aio_test.c
Show All 33 Lines | |||||
* fd is used for write and read (i.e., file, md device), but for others the | * fd is used for write and read (i.e., file, md device), but for others the | ||||
* operation is performed on a peer (pty, socket, fifo, etc). For each file | * operation is performed on a peer (pty, socket, fifo, etc). For each file | ||||
* descriptor type, several completion methods are tested. This test program | * descriptor type, several completion methods are tested. This test program | ||||
* does not attempt to exercise error cases or more subtle asynchronous | * does not attempt to exercise error cases or more subtle asynchronous | ||||
* behavior, just make sure that the basic operations work on some basic object | * behavior, just make sure that the basic operations work on some basic object | ||||
* types. | * types. | ||||
*/ | */ | ||||
#include <sys/event.h> | |||||
#include <sys/param.h> | #include <sys/param.h> | ||||
#include <sys/mdioctl.h> | #include <sys/mdioctl.h> | ||||
#include <sys/module.h> | #include <sys/module.h> | ||||
#include <sys/resource.h> | #include <sys/resource.h> | ||||
#include <sys/socket.h> | #include <sys/socket.h> | ||||
#include <sys/stat.h> | #include <sys/stat.h> | ||||
#include <sys/un.h> | #include <sys/un.h> | ||||
#include <aio.h> | #include <aio.h> | ||||
#include <err.h> | #include <err.h> | ||||
#include <errno.h> | #include <errno.h> | ||||
#include <fcntl.h> | #include <fcntl.h> | ||||
#include <libutil.h> | #include <libutil.h> | ||||
#include <limits.h> | #include <limits.h> | ||||
#include <pthread.h> | |||||
#include <semaphore.h> | #include <semaphore.h> | ||||
#include <signal.h> | #include <signal.h> | ||||
#include <stdint.h> | #include <stdint.h> | ||||
#include <stdio.h> | #include <stdio.h> | ||||
#include <stdlib.h> | #include <stdlib.h> | ||||
#include <string.h> | #include <string.h> | ||||
#include <termios.h> | #include <termios.h> | ||||
#include <unistd.h> | #include <unistd.h> | ||||
▲ Show 20 Lines • Show All 1,845 Lines • ▼ Show 20 Lines | if (atf_tc_get_config_var_as_bool_wd(tc, "ci", false)) | ||||
atf_tc_skip("https://bugs.freebsd.org/258766"); | atf_tc_skip("https://bugs.freebsd.org/258766"); | ||||
aio_zvol_test(poll, NULL, true); | aio_zvol_test(poll, NULL, true); | ||||
} | } | ||||
ATF_TC_CLEANUP(vectored_zvol_poll, tc) | ATF_TC_CLEANUP(vectored_zvol_poll, tc) | ||||
{ | { | ||||
aio_zvol_cleanup(); | aio_zvol_cleanup(); | ||||
} | } | ||||
static void * | |||||
aio_threadexit_run(void *arg) | |||||
{ | |||||
struct aiocb *iocb; | |||||
intptr_t rc; | |||||
iocb = arg; | |||||
rc = aio_write(iocb); | |||||
return ((void *)rc); | |||||
} | |||||
ATF_TC_WITHOUT_HEAD(aio_threadexit); | |||||
ATF_TC_BODY(aio_threadexit, tc) | |||||
{ | |||||
char buffer[] = "hello"; | |||||
struct timespec zero_timeout = {0, 0}; | |||||
pthread_t threads[sizeof(buffer)]; | |||||
struct aiocb iocbs[sizeof(buffer)]; | |||||
struct aiocb *iocbp; | |||||
int fd; | |||||
ATF_REQUIRE_KERNEL_MODULE("aio"); | |||||
ATF_REQUIRE_UNSAFE_AIO(); | |||||
fd = open(FILE_PATHNAME, O_RDWR | O_CREAT, 0600); | |||||
ATF_REQUIRE(fd >= 0); | |||||
/* Start all the threads, one per byte in buffer. */ | |||||
for (unsigned i = 0; i < nitems(threads); ++i) { | |||||
memset(&iocbs[i], 0, sizeof(iocbs[i])); | |||||
iocbs[i].aio_sigevent.sigev_notify = SIGEV_NONE; | |||||
iocbs[i].aio_fildes = fd; | |||||
iocbs[i].aio_buf = &buffer[i]; | |||||
iocbs[i].aio_nbytes = 1; | |||||
iocbs[i].aio_offset = i; | |||||
ATF_REQUIRE_EQ(0, pthread_create(&threads[i], NULL, | |||||
aio_threadexit_run, &iocbs[i])); | |||||
} | |||||
/* Wait for all the threads to exit. */ | |||||
for (unsigned i = 0; i < nitems(threads); ++i) { | |||||
void *result; | |||||
ATF_REQUIRE_EQ(0, pthread_join(threads[i], &result)); | |||||
ATF_REQUIRE_EQ(0, result); | |||||
} | |||||
/* Reap the completed IOs, zero timeout should be sufficent.. */ | |||||
asomers: Why are you sure that a zero timeout will be sufficient? I think you should use a NULL timeout… | |||||
for (unsigned i = 0; i < nitems(threads); ++i) { | |||||
ATF_REQUIRE_EQ(1, aio_waitcomplete(&iocbp, &zero_timeout)); | |||||
} | |||||
/* Nothing more in the kernel's queue. */ | |||||
ATF_REQUIRE_EQ(-1, aio_waitcomplete(&iocbp, &zero_timeout)); | |||||
ATF_REQUIRE_EQ(errno, EAGAIN); | |||||
/* Read the data back to see that our writes all worked. */ | |||||
ATF_REQUIRE_EQ(sizeof(buffer), pread(fd, buffer, sizeof(buffer), 0)); | |||||
ATF_REQUIRE_EQ(0, strcmp("hello", buffer)); | |||||
close(fd); | |||||
} | |||||
ATF_TP_ADD_TCS(tp) | ATF_TP_ADD_TCS(tp) | ||||
{ | { | ||||
ATF_TP_ADD_TC(tp, file_poll); | ATF_TP_ADD_TC(tp, file_poll); | ||||
ATF_TP_ADD_TC(tp, file_signal); | ATF_TP_ADD_TC(tp, file_signal); | ||||
ATF_TP_ADD_TC(tp, file_suspend); | ATF_TP_ADD_TC(tp, file_suspend); | ||||
ATF_TP_ADD_TC(tp, file_thread); | ATF_TP_ADD_TC(tp, file_thread); | ||||
ATF_TP_ADD_TC(tp, file_waitcomplete); | ATF_TP_ADD_TC(tp, file_waitcomplete); | ||||
Show All 40 Lines | ATF_TP_ADD_TCS(tp) | ||||
ATF_TP_ADD_TC(tp, aio_writev_empty_file_signal); | ATF_TP_ADD_TC(tp, aio_writev_empty_file_signal); | ||||
ATF_TP_ADD_TC(tp, vectored_big_iovcnt); | ATF_TP_ADD_TC(tp, vectored_big_iovcnt); | ||||
ATF_TP_ADD_TC(tp, vectored_file_poll); | ATF_TP_ADD_TC(tp, vectored_file_poll); | ||||
ATF_TP_ADD_TC(tp, vectored_md_poll); | ATF_TP_ADD_TC(tp, vectored_md_poll); | ||||
ATF_TP_ADD_TC(tp, vectored_zvol_poll); | ATF_TP_ADD_TC(tp, vectored_zvol_poll); | ||||
ATF_TP_ADD_TC(tp, vectored_unaligned); | ATF_TP_ADD_TC(tp, vectored_unaligned); | ||||
ATF_TP_ADD_TC(tp, vectored_socket_poll); | ATF_TP_ADD_TC(tp, vectored_socket_poll); | ||||
ATF_TP_ADD_TC(tp, vectored_thread); | ATF_TP_ADD_TC(tp, vectored_thread); | ||||
ATF_TP_ADD_TC(tp, aio_threadexit); | |||||
return (atf_no_error()); | return (atf_no_error()); | ||||
} | } |
Why are you sure that a zero timeout will be sufficient? I think you should use a NULL timeout instead, to wait forever if necessary.