aboutsummaryrefslogtreecommitdiff
path: root/src/internal
diff options
context:
space:
mode:
authorIan Lance Taylor <iant@golang.org>2022-10-04 14:35:39 -0700
committerGopher Robot <gobot@golang.org>2022-10-08 03:57:40 +0000
commit4fe1971b2dff1fa14cb8f5be47aed7fda76c0f7c (patch)
treedc3dbd8b4e173595674c520a1860fbcb0b17ac97 /src/internal
parent669ec549b554ef7fe957bf284271ed3b7db82da1 (diff)
downloadgo-4fe1971b2dff1fa14cb8f5be47aed7fda76c0f7c.tar.xz
os: use poll.fdMutex for Plan 9 files
This permits us to safely support concurrent access to files on Plan 9. Concurrent access was already safe on other systems. This does introduce a change: if one goroutine calls a blocking read on a pipe, and another goroutine closes the pipe, then before this CL the close would occur. Now the close will be delayed until the blocking read completes. Also add tests that concurrent I/O and Close on a pipe are OK. For #50436 For #56043 Change-Id: I969c869ea3b8c5c2f2ef319e441a56a3c64e7bf5 Reviewed-on: https://go-review.googlesource.com/c/go/+/438347 Reviewed-by: Bryan Mills <bcmills@google.com> Reviewed-by: Ian Lance Taylor <iant@google.com> Reviewed-by: David du Colombier <0intro@gmail.com> Run-TryBot: Ian Lance Taylor <iant@google.com> Auto-Submit: Ian Lance Taylor <iant@google.com> TryBot-Result: Gopher Robot <gobot@golang.org> Reviewed-by: Rob Pike <r@golang.org>
Diffstat (limited to 'src/internal')
-rw-r--r--src/internal/poll/export_test.go12
-rw-r--r--src/internal/poll/fd_mutex_test.go12
-rw-r--r--src/internal/poll/file_plan9.go42
3 files changed, 54 insertions, 12 deletions
diff --git a/src/internal/poll/export_test.go b/src/internal/poll/export_test.go
index 02664d9ea3..66d7c3274b 100644
--- a/src/internal/poll/export_test.go
+++ b/src/internal/poll/export_test.go
@@ -10,26 +10,26 @@ package poll
var Consume = consume
-type FDMutex struct {
+type XFDMutex struct {
fdMutex
}
-func (mu *FDMutex) Incref() bool {
+func (mu *XFDMutex) Incref() bool {
return mu.incref()
}
-func (mu *FDMutex) IncrefAndClose() bool {
+func (mu *XFDMutex) IncrefAndClose() bool {
return mu.increfAndClose()
}
-func (mu *FDMutex) Decref() bool {
+func (mu *XFDMutex) Decref() bool {
return mu.decref()
}
-func (mu *FDMutex) RWLock(read bool) bool {
+func (mu *XFDMutex) RWLock(read bool) bool {
return mu.rwlock(read)
}
-func (mu *FDMutex) RWUnlock(read bool) bool {
+func (mu *XFDMutex) RWUnlock(read bool) bool {
return mu.rwunlock(read)
}
diff --git a/src/internal/poll/fd_mutex_test.go b/src/internal/poll/fd_mutex_test.go
index 3029b9a681..62f953192d 100644
--- a/src/internal/poll/fd_mutex_test.go
+++ b/src/internal/poll/fd_mutex_test.go
@@ -14,7 +14,7 @@ import (
)
func TestMutexLock(t *testing.T) {
- var mu FDMutex
+ var mu XFDMutex
if !mu.Incref() {
t.Fatal("broken")
@@ -39,7 +39,7 @@ func TestMutexLock(t *testing.T) {
}
func TestMutexClose(t *testing.T) {
- var mu FDMutex
+ var mu XFDMutex
if !mu.IncrefAndClose() {
t.Fatal("broken")
}
@@ -60,7 +60,7 @@ func TestMutexClose(t *testing.T) {
func TestMutexCloseUnblock(t *testing.T) {
c := make(chan bool, 4)
- var mu FDMutex
+ var mu XFDMutex
mu.RWLock(true)
for i := 0; i < 4; i++ {
go func() {
@@ -104,7 +104,7 @@ func TestMutexPanic(t *testing.T) {
f()
}
- var mu FDMutex
+ var mu XFDMutex
ensurePanics(func() { mu.Decref() })
ensurePanics(func() { mu.RWUnlock(true) })
ensurePanics(func() { mu.RWUnlock(false) })
@@ -137,7 +137,7 @@ func TestMutexOverflowPanic(t *testing.T) {
}
}()
- var mu1 FDMutex
+ var mu1 XFDMutex
for i := 0; i < 1<<21; i++ {
mu1.Incref()
}
@@ -152,7 +152,7 @@ func TestMutexStress(t *testing.T) {
}
defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(P))
done := make(chan bool, P)
- var mu FDMutex
+ var mu XFDMutex
var readState [2]uint64
var writeState [2]uint64
for p := 0; p < P; p++ {
diff --git a/src/internal/poll/file_plan9.go b/src/internal/poll/file_plan9.go
new file mode 100644
index 0000000000..57dc0c668f
--- /dev/null
+++ b/src/internal/poll/file_plan9.go
@@ -0,0 +1,42 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package poll
+
+// Expose fdMutex for use by the os package on Plan 9.
+// On Plan 9 we don't want to use async I/O for file operations,
+// but we still want the locking semantics that fdMutex provides.
+
+// FDMutex is an exported fdMutex, only for Plan 9.
+type FDMutex struct {
+ fdmu fdMutex
+}
+
+func (fdmu *FDMutex) Incref() bool {
+ return fdmu.fdmu.incref()
+}
+
+func (fdmu *FDMutex) Decref() bool {
+ return fdmu.fdmu.decref()
+}
+
+func (fdmu *FDMutex) IncrefAndClose() bool {
+ return fdmu.fdmu.increfAndClose()
+}
+
+func (fdmu *FDMutex) ReadLock() bool {
+ return fdmu.fdmu.rwlock(true)
+}
+
+func (fdmu *FDMutex) ReadUnlock() bool {
+ return fdmu.fdmu.rwunlock(true)
+}
+
+func (fdmu *FDMutex) WriteLock() bool {
+ return fdmu.fdmu.rwlock(false)
+}
+
+func (fdmu *FDMutex) WriteUnlock() bool {
+ return fdmu.fdmu.rwunlock(false)
+}