in testing/ostest/aio.c [280:662]
void aio_test(void)
{
struct sigevent sig;
sigset_t oset;
sigset_t set;
int completed;
int total;
int ret;
int i;
/* Block all signals except for SIGUSR1 and SIGALRM (for sleep) */
sigfillset(&set);
sigdelset(&set, SIGUSR1);
sigdelset(&set, SIGALRM);
sigprocmask(SIG_SETMASK, &set, &oset);
/* Case 1: Poll for transfer complete */
printf("AIO test case 1: Poll for transfer complete\n");
g_fildes = open(AIO_FILEPATH, O_RDWR | O_CREAT | O_TRUNC);
if (g_fildes < 0)
{
printf("aio_test: ERROR: Failed to open %s: %d\n",
AIO_FILEPATH, errno);
ASSERT(false);
goto errout_with_procmask;
}
init_aiocb(false);
ret = lio_listio(LIO_NOWAIT, g_aiocb, AIO_NCTRLBLKS, NULL);
if (ret < 0)
{
printf("aio_test: ERROR: lio_listio failed: %d\n", errno);
ASSERT(false);
goto errout_with_fildes;
}
do
{
usleep(500 * 1000);
ret = check_done();
}
while (ret < 0);
close(g_fildes);
g_fildes = -1;
/* Case 2: Wait in lio_listio */
/* Try to assure that this test does not overlap any activity from the
* task end of the last test case -- especially the dangling SIGPOLL.
*/
usleep(500 * 1000);
printf("AIO test case 2: Use LIO_WAIT for transfer complete\n");
g_fildes = open(AIO_FILEPATH, O_RDWR | O_CREAT | O_TRUNC);
if (g_fildes < 0)
{
printf("aio_test: ERROR: Failed to open %s: %d\n",
AIO_FILEPATH, errno);
ASSERT(false);
goto errout_with_procmask;
}
init_aiocb(false);
ret = lio_listio(LIO_WAIT, g_aiocb, AIO_NCTRLBLKS, NULL);
if (ret < 0)
{
printf("aio_test: ERROR: lio_listio failed: %d\n", errno);
ASSERT(false);
goto errout_with_fildes;
}
ret = check_done();
if (ret < 0)
{
printf("aio_test: ERROR: Not done\n");
ASSERT(false);
goto errout_with_fildes;
}
close(g_fildes);
g_fildes = -1;
/* Case 3: Use aio_suspend() until complete */
/* Try to assure that this test does not overlap any activity from the
* task end of the last test case -- especially the dangling SIGPOLL.
*/
usleep(500 * 1000);
printf("AIO test case 3: Use aio_suspend for transfer complete\n");
g_fildes = open(AIO_FILEPATH, O_RDWR | O_CREAT | O_TRUNC);
if (g_fildes < 0)
{
printf("aio_test: ERROR: Failed to open %s: %d\n",
AIO_FILEPATH, errno);
ASSERT(false);
goto errout_with_procmask;
}
init_aiocb(false);
ret = lio_listio(LIO_NOWAIT, g_aiocb, AIO_NCTRLBLKS, NULL);
if (ret < 0)
{
printf("aio_test: ERROR: lio_listio failed: %d\n", errno);
ASSERT(false);
goto errout_with_fildes;
}
total = 1; /* One entry was initially NULL */
for (i = 1; i <= AIO_NCTRLBLKS; i++)
{
printf(" Calling aio_suspend #%d\n", i);
ret = aio_suspend((FAR const struct aiocb *const *)g_aiocb,
AIO_NCTRLBLKS, NULL);
if (ret < 0)
{
printf("aio_test: ERROR: aio_suspend failed: %d\n", errno);
ASSERT(false);
goto errout_with_fildes;
}
completed = remove_done();
if (completed < 1)
{
printf("aio_test: ERROR: Signalled, but no I/O completed\n");
ASSERT(false);
goto errout_with_fildes;
}
total += completed;
printf(" Completed=%d\n", total);
if (total >= AIO_NCTRLBLKS)
{
break;
}
}
if (total != AIO_NCTRLBLKS)
{
printf("aio_test: ERROR: Total is %d, should be %d\n",
total, AIO_NCTRLBLKS);
ASSERT(false);
goto errout_with_fildes;
}
close(g_fildes);
g_fildes = -1;
/* Case 4: Use individual signals */
/* Try to assure that this test does not overlap any activity from the
* task end of the last test case -- especially the dangling SIGPOLL.
*/
usleep(500 * 1000);
printf("AIO test case 4: Use individual signals for transfer complete\n");
g_fildes = open(AIO_FILEPATH, O_RDWR | O_CREAT | O_TRUNC);
if (g_fildes < 0)
{
printf("aio_test: ERROR: Failed to open %s: %d\n",
AIO_FILEPATH, errno);
ASSERT(false);
goto errout_with_procmask;
}
init_aiocb(true);
ret = lio_listio(LIO_NOWAIT, g_aiocb, AIO_NCTRLBLKS, NULL);
if (ret < 0)
{
printf("aio_test: ERROR: lio_listio failed: %d\n", errno);
ASSERT(false);
goto errout_with_fildes;
}
sigemptyset(&set);
sigaddset(&set, SIGUSR1);
do
{
ret = check_done();
if (ret < 0)
{
int status = sigwaitinfo(&set, NULL);
if (status < 0)
{
int errcode = errno;
if (errcode == EINTR)
{
printf(" Interrupted by a signal)\n");
}
else
{
printf("aio_test: ERROR: sigwaitinfo failed: %d\n",
errcode);
ASSERT(false);
goto errout_with_fildes;
}
}
else
{
printf(" Received signal %d\n", status);
}
}
}
while (ret < 0);
close(g_fildes);
g_fildes = -1;
/* Case 5: Use list complete signal */
/* Try to assure that this test does not overlap any activity from the
* task end of the last test case -- especially the dangling SIGPOLL.
*/
usleep(500 * 1000);
printf("AIO test case 5:"
" Use list complete signal for transfer complete\n");
g_fildes = open(AIO_FILEPATH, O_RDWR | O_CREAT | O_TRUNC);
if (g_fildes < 0)
{
printf("aio_test: ERROR: Failed to open %s: %d\n",
AIO_FILEPATH, errno);
ASSERT(false);
goto errout_with_procmask;
}
init_aiocb(false);
sig.sigev_notify = SIGEV_SIGNAL;
sig.sigev_signo = SIGUSR1;
sig.sigev_value.sival_ptr = NULL;
ret = lio_listio(LIO_NOWAIT, g_aiocb, AIO_NCTRLBLKS, &sig);
if (ret < 0)
{
printf("aio_test: ERROR: lio_listio failed: %d\n", errno);
ASSERT(false);
goto errout_with_fildes;
}
sigemptyset(&set);
sigaddset(&set, SIGUSR1);
do
{
ret = check_done();
if (ret < 0)
{
int status = sigwaitinfo(&set, NULL);
if (status < 0)
{
int errcode = errno;
if (errcode == EINTR)
{
printf("aio_test: Interrupted by a signal\n");
}
else
{
printf("aio_test: ERROR: sigwaitinfo failed: %d\n",
errcode);
ASSERT(false);
goto errout_with_fildes;
}
}
}
}
while (ret < 0);
close(g_fildes);
g_fildes = -1;
/* Case 6: Cancel I/O by AIO control block */
/* Try to assure that this test does not overlap any activity from the
* task end of the last test case -- especially the dangling SIGPOLL.
*/
usleep(500 * 1000);
printf("AIO test case 6: Cancel I/O by AIO control block\n");
g_fildes = open(AIO_FILEPATH, O_RDWR | O_CREAT | O_TRUNC);
if (g_fildes < 0)
{
printf("aio_test: ERROR: Failed to open %s: %d\n",
AIO_FILEPATH, errno);
ASSERT(false);
goto errout_with_procmask;
}
init_aiocb(false);
ret = lio_listio(LIO_NOWAIT, g_aiocb, AIO_NCTRLBLKS, NULL);
if (ret < 0)
{
printf("aio_test: ERROR: lio_listio failed: %d\n", errno);
ASSERT(false);
goto errout_with_fildes;
}
ret = aio_cancel(g_fildes, g_aiocb[2]);
if (ret < 0)
{
printf("aio_test: ERROR: aio_cancel failed: %d\n", errno);
ASSERT(false);
goto errout_with_fildes;
}
printf(" aio_cancel return %d\n", ret);
do
{
usleep(500 * 1000);
ret = check_done();
}
while (ret < 0);
close(g_fildes);
g_fildes = -1;
/* Case 7: Cancel I/O by file descriptor */
/* Try to assure that this test does not overlap any activity from the
* task end of the last test case -- especially the dangling SIGPOLL.
*/
usleep(500 * 1000);
printf("AIO test case 7:Cancel I/O by file descriptor\n");
g_fildes = open(AIO_FILEPATH, O_RDWR | O_CREAT | O_TRUNC);
if (g_fildes < 0)
{
printf("aio_test: ERROR: Failed to open %s: %d\n",
AIO_FILEPATH, errno);
ASSERT(false);
goto errout_with_procmask;
}
init_aiocb(false);
ret = lio_listio(LIO_NOWAIT, g_aiocb, AIO_NCTRLBLKS, NULL);
if (ret < 0)
{
printf("aio_test: ERROR: lio_listio failed: %d\n", errno);
ASSERT(false);
goto errout_with_fildes;
}
ret = aio_cancel(g_fildes, NULL);
if (ret < 0)
{
printf("aio_test: ERROR: aio_cancel failed: %d\n", errno);
ASSERT(false);
goto errout_with_fildes;
}
printf(" aio_cancel return %d\n", ret);
do
{
usleep(500 * 1000);
ret = check_done();
}
while (ret < 0);
sigprocmask(SIG_SETMASK, &oset, NULL);
printf("aio_test: Test completed successfully\n");
return;
errout_with_fildes:
close(g_fildes);
g_fildes = -1;
errout_with_procmask:
sigprocmask(SIG_SETMASK, &oset, NULL);
printf("aio_test: ERROR: Test aborted\n");
}