From eaa6475dbbf73c0efe6ba2b5e28ea126c22b7286 Mon Sep 17 00:00:00 2001 From: qmuntal Date: Tue, 17 Feb 2026 13:59:51 +0100 Subject: internal/poll: readWriteLock should destroy the fd when there are no more references to it The read lock in readWriteLock might be holding the last reference to the fd. If the fd is closed while the read lock is still held, then the fd will not be destroyed until the read lock is released and fd.destroy is called. The race windows is small and difficult to trigger on real workloads, but it has been observed in CI. Fixes #77609 Fixes #74754 (tentatively) Change-Id: I17be2d23dced1258e1a986c7359e27a81fc51c53 Reviewed-on: https://go-review.googlesource.com/c/go/+/745601 Reviewed-by: Mark Freeman Reviewed-by: Damien Neil LUCI-TryBot-Result: Go LUCI --- src/internal/poll/fd_mutex.go | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/internal/poll/fd_mutex.go b/src/internal/poll/fd_mutex.go index aba22e9867..300628db79 100644 --- a/src/internal/poll/fd_mutex.go +++ b/src/internal/poll/fd_mutex.go @@ -269,7 +269,9 @@ func (fd *FD) readWriteLock() error { return errClosing(fd.isFile) } if !fd.fdmu.rwlock(writeLock, waitLock) { - fd.fdmu.rwunlock(readlock) // unlock read lock acquired above + if fd.fdmu.rwunlock(readlock) { + fd.destroy() + } return errClosing(fd.isFile) } return nil @@ -286,7 +288,9 @@ func (fd *FD) tryReadWriteLock() (bool, error) { return false, nil } if !fd.fdmu.rwlock(writeLock, tryLock) { - fd.fdmu.rwunlock(readlock) // unlock read lock acquired above + if fd.fdmu.rwunlock(readlock) { + fd.destroy() + } if fd.closing() { return false, errClosing(fd.isFile) } -- cgit v1.3