diff options
-rw-r--r-- | apps/examples/ostest/aio.c | 62 | ||||
-rw-r--r-- | nuttx/fs/aio/aio_signal.c | 16 |
2 files changed, 72 insertions, 6 deletions
diff --git a/apps/examples/ostest/aio.c b/apps/examples/ostest/aio.c index ad781325f..b7560259c 100644 --- a/apps/examples/ostest/aio.c +++ b/apps/examples/ostest/aio.c @@ -283,6 +283,9 @@ static int remove_done(void) void aio_test(void) { + struct sigevent sig; + sigset_t oset; + sigset_t set; int ret; int i; @@ -380,7 +383,6 @@ void aio_test(void) close(g_fildes); g_fildes = -1; - /* Case 4: Use individual signals */ printf("AIO test case 4: Use individual signals for transfer complete\n"); @@ -389,7 +391,63 @@ void aio_test(void) /* Case 5: Use list complete signal */ printf("AIO test case 5: Use list complete signal for transfer complete\n"); - /* REVISIT: Not yet implemented */ + 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); + return; + } + + init_aiocb(false); + + sigemptyset(&set); + sigaddset(&set, SIGUSR1); + + /* Block all signals except for SIGUSR1 */ + + sigfillset(&set); + sigdelset(&set, SIGUSR1); + (void)sigprocmask(SIG_SETMASK, &set, &oset); + + 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); + (void)sigprocmask(SIG_SETMASK, &oset, NULL); + return; + } + + 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); + (void)sigprocmask(SIG_SETMASK, &oset, NULL); + return; + } + } + } + } + while (ret < 0); + + close(g_fildes); + g_fildes = -1; + (void)sigprocmask(SIG_SETMASK, &oset, NULL); /* Case 6: Cancel I/O by AIO control block */ diff --git a/nuttx/fs/aio/aio_signal.c b/nuttx/fs/aio/aio_signal.c index 3e46f95da..9545a8622 100644 --- a/nuttx/fs/aio/aio_signal.c +++ b/nuttx/fs/aio/aio_signal.c @@ -96,6 +96,9 @@ int aio_signal(pid_t pid, FAR struct aiocb *aiocbp) { +#ifdef CONFIG_CAN_PASS_STRUCTS + union sigval value; +#endif int errcode; int status; int ret; @@ -115,10 +118,10 @@ int aio_signal(pid_t pid, FAR struct aiocb *aiocbp) status = sigqueue(pid, aiocbp->aio_sigevent.sigev_sign, aiocbp->aio_sigevent.sigev_value.sival_ptr); #endif - if (ret < 0) + if (status < 0) { errcode = get_errno(); - fdbg("ERROR: sigqueue failed: %d\n", errcode); + fdbg("ERROR: sigqueue #1 failed: %d\n", errcode); ret = ERROR; } } @@ -127,11 +130,16 @@ int aio_signal(pid_t pid, FAR struct aiocb *aiocbp) * on sig_suspend(); */ - status = kill(pid, SIGPOLL); +#ifdef CONFIG_CAN_PASS_STRUCTS + value.sival_ptr = aiocbp; + status = sigqueue(pid, SIGPOLL, value); +#else + status = sigqueue(pid, SIGPOLL, aiocbp); +#endif if (status && ret == OK) { errcode = get_errno(); - fdbg("ERROR: kill failed: %d\n", errcode); + fdbg("ERROR: sigqueue #2 failed: %d\n", errcode); ret = ERROR; } |