-
Notifications
You must be signed in to change notification settings - Fork 18.3k
Closed
Labels
Description
I've got a simple package to protect map from concurrent read/writes via sync.Mutex. But from time to time I get panic concurrent map writes
.
Can you guys see any issue with the below code? What am I doing wrong? Or is this a Go bug?
What did you do?
package stringmap
import "sync"
// concurrentStringMap is a concurrent storage for strings (emails, links etc.)
// that automatically removes duplicates. Very helpful for verifying output
// of Newsletter recipients or URL links in Newsletter HTML/Text.
type concurrentStringMap struct {
sync.Mutex
strings map[string]struct{}
}
func NewConcurrentStringMap() concurrentStringMap {
return concurrentStringMap{
strings: map[string]struct{}{},
}
}
func (u concurrentStringMap) Add(str string) bool {
u.Lock()
defer u.Unlock()
if _, ok := u.strings[str]; ok {
return false
}
u.strings[str] = struct{}{} // panic happens here
return true
}
func (u concurrentStringMap) Slice() []string {
u.Lock()
defer u.Unlock()
slice := make([]string, 0, len(u.strings))
for str, _ := range u.strings {
slice = append(slice, str)
}
return slice
}
What did you expect to see?
No panic?
What did you see instead?
fatal error: concurrent map writes
goroutine 1194 [running]:
runtime.throw(0x1fe22bf, 0x15)
/usr/local/go/src/runtime/panic.go:596 +0x95 fp=0xc420ca8dc8 sp=0xc420ca8da8
runtime.mapassign(0x1e03b40, 0xc420bbb890, 0xc420ca8ea0, 0x1b)
/usr/local/go/src/runtime/hashmap.go:499 +0x667 fp=0xc420ca8e68 sp=0xc420ca8dc8
github.com/pressly/api/lib/stringmap.concurrentStringMap.Add(0x0, 0xc420bbb890, 0xc420ec7560, 0x1b, 0x0)
***/stringmap/stringmap.go:25 +0x127 fp=0xc420ca8ec0 sp=0xc420ca8e68
Does this issue reproduce with the latest release (go1.8.1)?
System details
go version go1.8 darwin/amd64
GOARCH="amd64"
GOBIN=""
GOEXE=""
GOHOSTARCH="amd64"
GOHOSTOS="darwin"
GOOS="darwin"
GOPATH="/Users/vojtechvitek/go"
GORACE=""
GOROOT="/usr/local/go"
GOTOOLDIR="/usr/local/go/pkg/tool/darwin_amd64"
GCCGO="gccgo"
CC="clang"
GOGCCFLAGS="-fPIC -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/hr/5zb8r0yx4sv4_1dc0rlccflm0000gn/T/go-build257984097=/tmp/go-build -gno-record-gcc-switches -fno-common"
CXX="clang++"
CGO_ENABLED="1"
PKG_CONFIG="pkg-config"
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
GOROOT/bin/go version: go version go1.8 darwin/amd64
GOROOT/bin/go tool compile -V: compile version go1.8 X:framepointer
uname -v: Darwin Kernel Version 16.4.0: Thu Dec 22 22:53:21 PST 2016; root:xnu-3789.41.3~3/RELEASE_X86_64
ProductName: Mac OS X
ProductVersion: 10.12.3
BuildVersion: 16D32
lldb --version: lldb-370.0.40
Swift-3.1