summaryrefslogtreecommitdiff
path: root/src/pkg/sync/mutex.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/pkg/sync/mutex.go')
-rw-r--r--src/pkg/sync/mutex.go15
1 files changed, 10 insertions, 5 deletions
diff --git a/src/pkg/sync/mutex.go b/src/pkg/sync/mutex.go
index c4d82af00..2a1270b9c 100644
--- a/src/pkg/sync/mutex.go
+++ b/src/pkg/sync/mutex.go
@@ -3,10 +3,10 @@
// license that can be found in the LICENSE file.
// The sync package provides basic synchronization primitives
-// such as mutual exclusion locks. Other than the Once type,
-// most are intended for use by low-level library routines.
-// Higher-level synchronization is better done via channels
-// and communication.
+// such as mutual exclusion locks. Other than the Once and
+// WaitGroup types, most are intended for use by low-level
+// library routines. Higher-level synchronization is better
+// done via channels and communication.
package sync
import "runtime"
@@ -53,9 +53,14 @@ func (m *Mutex) Lock() {
// It is allowed for one goroutine to lock a Mutex and then
// arrange for another goroutine to unlock it.
func (m *Mutex) Unlock() {
- if xadd(&m.key, -1) == 0 {
+ switch v := xadd(&m.key, -1); {
+ case v == 0:
// changed from 1 to 0; no contention
return
+ case int32(v) == -1:
+ // changed from 0 to -1: wasn't locked
+ // (or there are 4 billion goroutines waiting)
+ panic("sync: unlock of unlocked mutex")
}
runtime.Semrelease(&m.sema)
}