diff options
author | Ian Lance Taylor <iant@golang.org> | 2018-06-19 20:43:24 -0700 |
---|---|---|
committer | Ian Lance Taylor <iant@golang.org> | 2018-06-20 16:55:30 +0000 |
commit | 3ca5b7c5b21574da0b29ea1d2d53ffce8711d225 (patch) | |
tree | e115c88a032a298281260f52ec95bb517473ceb3 | |
parent | 578e0668627229ad0b9a3c88b61b3489cedb9074 (diff) | |
download | go-3ca5b7c5b21574da0b29ea1d2d53ffce8711d225.tar.gz go-3ca5b7c5b21574da0b29ea1d2d53ffce8711d225.zip |
internal/poll: better panic message for lock overflow
Instead of "inconsistent poll.fdMutex", panic with
"too many concurrent operations on a single file or socket (max 1048575)".
Fixes #25558
Change-Id: I5cad3633aa539fb6f48cca236c6656c86acfb663
Reviewed-on: https://go-review.googlesource.com/119956
Run-TryBot: Ian Lance Taylor <iant@golang.org>
Run-TryBot: Dmitry Vyukov <dvyukov@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Dmitry Vyukov <dvyukov@google.com>
-rw-r--r-- | src/internal/poll/fd_mutex.go | 10 | ||||
-rw-r--r-- | src/internal/poll/fd_mutex_test.go | 22 |
2 files changed, 28 insertions, 4 deletions
diff --git a/src/internal/poll/fd_mutex.go b/src/internal/poll/fd_mutex.go index 2ba7de7da3..0a8ee6f0d4 100644 --- a/src/internal/poll/fd_mutex.go +++ b/src/internal/poll/fd_mutex.go @@ -34,6 +34,8 @@ const ( mutexWMask = (1<<20 - 1) << 43 ) +const overflowMsg = "too many concurrent operations on a single file or socket (max 1048575)" + // Read operations must do rwlock(true)/rwunlock(true). // // Write operations must do rwlock(false)/rwunlock(false). @@ -56,7 +58,7 @@ func (mu *fdMutex) incref() bool { } new := old + mutexRef if new&mutexRefMask == 0 { - panic("inconsistent poll.fdMutex") + panic(overflowMsg) } if atomic.CompareAndSwapUint64(&mu.state, old, new) { return true @@ -75,7 +77,7 @@ func (mu *fdMutex) increfAndClose() bool { // Mark as closed and acquire a reference. new := (old | mutexClosed) + mutexRef if new&mutexRefMask == 0 { - panic("inconsistent poll.fdMutex") + panic(overflowMsg) } // Remove all read and write waiters. new &^= mutexRMask | mutexWMask @@ -136,13 +138,13 @@ func (mu *fdMutex) rwlock(read bool) bool { // Lock is free, acquire it. new = (old | mutexBit) + mutexRef if new&mutexRefMask == 0 { - panic("inconsistent poll.fdMutex") + panic(overflowMsg) } } else { // Wait for lock. new = old + mutexWait if new&mutexMask == 0 { - panic("inconsistent poll.fdMutex") + panic(overflowMsg) } } if atomic.CompareAndSwapUint64(&mu.state, old, new) { diff --git a/src/internal/poll/fd_mutex_test.go b/src/internal/poll/fd_mutex_test.go index bab81c6dfe..2c53c4561f 100644 --- a/src/internal/poll/fd_mutex_test.go +++ b/src/internal/poll/fd_mutex_test.go @@ -8,6 +8,7 @@ import ( . "internal/poll" "math/rand" "runtime" + "strings" "testing" "time" ) @@ -121,6 +122,27 @@ func TestMutexPanic(t *testing.T) { mu.RWUnlock(false) } +func TestMutexOverflowPanic(t *testing.T) { + defer func() { + r := recover() + if r == nil { + t.Fatal("did not panic") + } + msg, ok := r.(string) + if !ok { + t.Fatalf("unexpected panic type %T", r) + } + if !strings.Contains(msg, "too many") || strings.Contains(msg, "inconsistent") { + t.Fatalf("wrong panic message %q", msg) + } + }() + + var mu1 FDMutex + for i := 0; i < 1<<21; i++ { + mu1.Incref() + } +} + func TestMutexStress(t *testing.T) { P := 8 N := int(1e6) |