This is an automated email from the ASF dual-hosted git repository. acassis pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/nuttx.git
commit 41f29b32e93c8c0463c0af1ede50d5a647cf487b Author: Xiang Xiao <[email protected]> AuthorDate: Fri Sep 11 02:22:26 2026 +0800 libc/aio: loop in aio_suspend() until a listed request completes aio_suspend() checked the completion status once and then performed a single sigtimedwait(). Any SIGPOLL delivered by an unrelated AIO operation (one not referenced by 'list') woke the caller even though none of the awaited requests had completed, and with a timeout the remaining wait time was not preserved either. Re-check the completion status after every wakeup and continue waiting, recomputing the remaining time from the absolute deadline so that the full timeout is honored. Signed-off-by: wushenhui <[email protected]> --- libs/libc/aio/aio_suspend.c | 64 +++++++++++++++++++++++++++++++-------------- 1 file changed, 44 insertions(+), 20 deletions(-) diff --git a/libs/libc/aio/aio_suspend.c b/libs/libc/aio/aio_suspend.c index d15b546f140..9b3d8f0e6c9 100644 --- a/libs/libc/aio/aio_suspend.c +++ b/libs/libc/aio/aio_suspend.c @@ -86,41 +86,65 @@ int aio_suspend(FAR const struct aiocb * const list[], int nent, FAR const struct timespec *timeout) { + struct timespec end; + struct timespec rem; sigset_t set; int ret; int i; DEBUGASSERT(list); - /* Check each entry in the list. Break out of the loop if any entry - * has completed. - */ + if (timeout) + { + clock_gettime(CLOCK_MONOTONIC, &end); + clock_timespec_add(&end, timeout, &end); + timeout = &rem; + } + + sigemptyset(&set); + sigaddset(&set, SIGPOLL); - for (i = 0; i < nent; i++) + for (; ; ) { - /* Check if the I/O has completed */ + /* Check each entry in the list. Break out of the loop if any entry + * has completed. + */ - if (list[i] && list[i]->aio_result != -EINPROGRESS) + for (i = 0; i < nent; i++) { - /* Yes, return success */ + /* Check if the I/O has completed */ + + if (list[i] && list[i]->aio_result != -EINPROGRESS) + { + /* Yes, return success */ - return OK; + return OK; + } } - } - /* Then wait for SIGPOLL. On success sigtimedwait() will return the - * signal number that cause the error (SIGPOLL). It will set errno - * appropriately for this function on errors. - * - * 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. - */ + /* Then wait for SIGPOLL. On success sigtimedwait() will return the + * signal number that cause the error (SIGPOLL). It will set errno + * appropriately for this function on errors. + * + * 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); + if (timeout) + { + clock_gettime(CLOCK_MONOTONIC, &rem); + clock_timespec_subtract(&end, &rem, &rem); + } + + ret = sigtimedwait(&set, NULL, timeout); + + if (ret < 0) + { + return ERROR; + } + } - ret = sigtimedwait(&set, NULL, timeout); - return ret >= 0 ? OK : ERROR; + return OK; } #endif /* CONFIG_FS_AIO */
