static void lio_sighandler(int signo, siginfo_t *info, void *ucontext) { FAR struct aiocb *aiocbp; FAR struct lio_sighand_s *sighand; int ret; DEBUGASSERT(signo == SIGPOLL && info); /* The info structure should contain a pointer to the AIO control block */ aiocbp = (FAR struct aiocb *)info->si_value.sival_ptr; DEBUGASSERT(aiocbp && aiocbp->aio_result != -EINPROGRESS); /* Recover our private data from the AIO control block */ sighand = (FAR struct lio_sighand_s *)aiocbp->aio_priv; DEBUGASSERT(sighand && sighand->list); aiocbp->aio_priv = NULL; /* Prevent any asynchronous I/O completions while the signal handler runs */ sched_lock(); /* Check if all of the pending I/O has completed */ ret = lio_checkio(sighand->list, sighand->nent); if (ret != -EINPROGRESS) { /* All pending I/O has completed */ /* Restore the signal handler */ (void)sigaction(SIGPOLL, &sighand->oact, NULL); /* Restore the sigprocmask */ (void)sigprocmask(SIG_SETMASK, &sighand->oprocmask, NULL); /* Signal the client */ if (sighand->sig->sigev_notify == SIGEV_SIGNAL) { #ifdef CONFIG_CAN_PASS_STRUCTS (void)sigqueue(sighand->pid, sighand->sig->sigev_signo, sighand->sig->sigev_value); #else (void)sigqueue(sighand->pid, sighand->sig->sigev_signo, sighand->sig->sigev_value.sival_ptr); #endif } /* And free the container */ lib_free(sighand); } sched_unlock(); }
static int lio_waitall(FAR struct aiocb * const *list, int nent) { sigset_t set; int ret; /* Loop until all I/O completes */ for (; ; ) { /* Check if all I/O has completed */ ret = lio_checkio(list, nent); if (ret != -EINPROGRESS) { /* All I/O has completed.. We are finished. */ return ret; } /* Then wait for SIGPOLL -- indefinitely. * * NOTE: If completion of the I/O causes other signals to be generated * first, then this will wake up and return EINTR instead of success. */ sigemptyset(&set); sigaddset(&set, SIGPOLL); ret = sigwaitinfo(&set, NULL); if (ret < 0) { /* The most likely reason that we would get here is because some * unrelated signal has been received. */ int errcode = get_errno(); ferr("ERROR: sigwaitinfo failed: %d\n", errcode); DEBUGASSERT(errcode > 0); return -errcode; } } }