summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGregory Nutt <gnutt@nuttx.org>2014-10-07 09:57:20 -0600
committerGregory Nutt <gnutt@nuttx.org>2014-10-07 09:57:20 -0600
commite4ac3239e0b0c22b2e911d739b69eaa7f69b3190 (patch)
tree72d7be137b6ac4b6c2f01d22cfa21e934bf9cb31
parent7c30b9eec161af92106dfa0daf1d0ea1590a8559 (diff)
downloadnuttx-e4ac3239e0b0c22b2e911d739b69eaa7f69b3190.tar.gz
nuttx-e4ac3239e0b0c22b2e911d739b69eaa7f69b3190.tar.bz2
nuttx-e4ac3239e0b0c22b2e911d739b69eaa7f69b3190.zip
AIO signal related fixes; extensino to AIO test
-rw-r--r--apps/examples/ostest/aio.c62
-rw-r--r--nuttx/fs/aio/aio_signal.c16
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;
}