aboutsummaryrefslogtreecommitdiff
path: root/src/image
diff options
context:
space:
mode:
authorTim Cooper <tim.cooper@layeh.com>2018-06-13 21:19:22 -0300
committerBrad Fitzpatrick <bradfitz@golang.org>2018-09-26 23:14:57 +0000
commit10aeb672e0183b63b6e2d59e49c38c8e83ea6113 (patch)
tree3fa7f435b6d393bc57de350faf4fb7dce1eafcea /src/image
parent94f48ddb96c4dfc919ae024f64df19d764f5fb5b (diff)
downloadgo-10aeb672e0183b63b6e2d59e49c38c8e83ea6113.tar.gz
go-10aeb672e0183b63b6e2d59e49c38c8e83ea6113.zip
image: make RegisterFormat safe for concurrent use
Fixes #25884 Change-Id: I5478846ef78aecac32078ea8c3248db52f1bb534 Reviewed-on: https://go-review.googlesource.com/118755 Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org> Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org>
Diffstat (limited to 'src/image')
-rw-r--r--src/image/format.go13
1 files changed, 11 insertions, 2 deletions
diff --git a/src/image/format.go b/src/image/format.go
index 3668de4e68..a53b8f9b55 100644
--- a/src/image/format.go
+++ b/src/image/format.go
@@ -8,6 +8,8 @@ import (
"bufio"
"errors"
"io"
+ "sync"
+ "sync/atomic"
)
// ErrFormat indicates that decoding encountered an unknown format.
@@ -21,7 +23,10 @@ type format struct {
}
// Formats is the list of registered formats.
-var formats []format
+var (
+ formatsMu sync.Mutex
+ atomicFormats atomic.Value
+)
// RegisterFormat registers an image format for use by Decode.
// Name is the name of the format, like "jpeg" or "png".
@@ -30,7 +35,10 @@ var formats []format
// Decode is the function that decodes the encoded image.
// DecodeConfig is the function that decodes just its configuration.
func RegisterFormat(name, magic string, decode func(io.Reader) (Image, error), decodeConfig func(io.Reader) (Config, error)) {
- formats = append(formats, format{name, magic, decode, decodeConfig})
+ formatsMu.Lock()
+ formats, _ := atomicFormats.Load().([]format)
+ atomicFormats.Store(append(formats, format{name, magic, decode, decodeConfig}))
+ formatsMu.Unlock()
}
// A reader is an io.Reader that can also peek ahead.
@@ -62,6 +70,7 @@ func match(magic string, b []byte) bool {
// Sniff determines the format of r's data.
func sniff(r reader) format {
+ formats, _ := atomicFormats.Load().([]format)
for _, f := range formats {
b, err := r.Peek(len(f.magic))
if err == nil && match(f.magic, b) {