aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorqmuntal <quimmuntal@gmail.com>2026-02-17 13:59:51 +0100
committerQuim Muntal <quimmuntal@gmail.com>2026-02-17 11:59:12 -0800
commiteaa6475dbbf73c0efe6ba2b5e28ea126c22b7286 (patch)
tree151c9dab1fdd0db723b8f5863d21622a4039e8f0
parent2eb890bde31495cdd90423fcfbc789351ca56ec6 (diff)
downloadgo-eaa6475dbbf73c0efe6ba2b5e28ea126c22b7286.tar.xz
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 <markfreeman@google.com> Reviewed-by: Damien Neil <dneil@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
-rw-r--r--src/internal/poll/fd_mutex.go8
1 files changed, 6 insertions, 2 deletions
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)
}