From 529b896bc27cb7dc2743ccbffa24b091c8a5cac4 Mon Sep 17 00:00:00 2001 From: Tero Salminen Date: Mon, 4 Nov 2024 14:48:40 +0200 Subject: [PATCH] fs_poll: race condition protection when modifying revents value pollfd revents value is occasionally zeroed by race condition when poll_notify() is called. This results to false timeout return value from poll(). This behaviour was found out when application called tcdrain() before calling uart poll(). Signed-off-by: Tero Salminen --- fs/vfs/fs_poll.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/fs/vfs/fs_poll.c b/fs/vfs/fs_poll.c index ba5f1a9920e5b..92dd47dfe5f21 100644 --- a/fs/vfs/fs_poll.c +++ b/fs/vfs/fs_poll.c @@ -275,6 +275,7 @@ void poll_notify(FAR struct pollfd **afds, int nfds, pollevent_t eventset) { int i; FAR struct pollfd *fds; + irqstate_t flags; DEBUGASSERT(afds != NULL && nfds >= 1); @@ -283,6 +284,9 @@ void poll_notify(FAR struct pollfd **afds, int nfds, pollevent_t eventset) fds = afds[i]; if (fds != NULL) { + /* race condition protection when modifying fds->revents */ + flags = enter_critical_section(); + /* The error event must be set in fds->revents */ fds->revents |= eventset & (fds->events | POLLERR | POLLHUP); @@ -293,6 +297,8 @@ void poll_notify(FAR struct pollfd **afds, int nfds, pollevent_t eventset) fds->revents &= ~POLLOUT; } + leave_critical_section(flags); + if ((fds->revents != 0 || (fds->events & POLLALWAYS) != 0) && fds->cb != NULL) {