This is an automated email from the ASF dual-hosted git repository.

xiaoxiang781216 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git


The following commit(s) were added to refs/heads/master by this push:
     new 94af12f6ac9 fs/epoll: decide the last close under the lock
94af12f6ac9 is described below

commit 94af12f6ac98548ddc8a153dd3fd7cebd0e8dfa4
Author: huangyulong3 <[email protected]>
AuthorDate: Wed Nov 11 15:31:17 2026 +0800

    fs/epoll: decide the last close under the lock
    
    epoll_do_close() decrements crefs under eph->lock but releases the lock
    before testing it.  Two threads closing the last two references can both
    read crefs <= 0 after the unlock, and both free the epoll head, or one
    frees it while the other still walks the lists.
    
    Test the count and tear down the lists while holding the lock, and
    destroy the lock only after the teardown.
    
    Signed-off-by: huangyulong3 <[email protected]>
    Signed-off-by: jingfei <[email protected]>
---
 fs/vfs/fs_epoll.c | 11 +++++++----
 1 file changed, 7 insertions(+), 4 deletions(-)

diff --git a/fs/vfs/fs_epoll.c b/fs/vfs/fs_epoll.c
index a89b918ab04..17473307306 100644
--- a/fs/vfs/fs_epoll.c
+++ b/fs/vfs/fs_epoll.c
@@ -193,11 +193,8 @@ static int epoll_do_close(FAR struct file *filep)
       return ret;
     }
 
-  eph->crefs--;
-  nxmutex_unlock(&eph->lock);
-  if (eph->crefs <= 0)
+  if (--eph->crefs <= 0)
     {
-      nxmutex_destroy(&eph->lock);
       list_for_every_entry(&eph->setup, epn, epoll_node_t, node)
         {
           file_poll(epn->filep, &epn->pfd, false);
@@ -220,8 +217,14 @@ static int epoll_do_close(FAR struct file *filep)
           fs_heap_free(epn);
         }
 
+      nxmutex_unlock(&eph->lock);
+      nxmutex_destroy(&eph->lock);
       fs_heap_free(eph);
     }
+  else
+    {
+      nxmutex_unlock(&eph->lock);
+    }
 
   return ret;
 }

Reply via email to