aboutsummaryrefslogtreecommitdiff
path: root/src
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 /src
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>
Diffstat (limited to 'src')
-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)
}