summaryrefslogtreecommitdiffstats
path: root/resource/image_cache.go
diff options
context:
space:
mode:
authorBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>2018-02-13 21:45:51 +0100
committerBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>2018-02-14 20:59:02 +0100
commit58382e9572559f88ed57f5c4899a37d489bcb220 (patch)
tree84a2616485e240f2cf5261e60d79a1bf45ae2b16 /resource/image_cache.go
parent53dac9a5067dfd84283a2b2d837738a63b63b596 (diff)
resource: Fix multi-threaded image processing issue
When doing something like this with the same image from a partial used in, say, both the home page and the single page: ```bash {{ with $img }} {{ $big := .Fill "1024x512 top" }} {{ $small := $big.Resize "512x" }} {{ end }} ``` There would be timing issues making Hugo in some cases try to process the same image with the same instructions in parallel. You would experience errors of type: ```bash png: invalid format: not enough pixel data ``` This commit works around that by adding a mutex per image. This should also improve the performance, sligthly, as it avoids duplicate work. The current workaround before this fix is to always operate on the original: ```bash {{ with $img }} {{ $big := .Fill "1024x512 top" }} {{ $small := .Fill "512x256 top" }} {{ end }} ``` Fixes #4404
Diffstat (limited to 'resource/image_cache.go')
-rw-r--r--resource/image_cache.go8
1 files changed, 7 insertions, 1 deletions
diff --git a/resource/image_cache.go b/resource/image_cache.go
index 5720fb623..250155db1 100644
--- a/resource/image_cache.go
+++ b/resource/image_cache.go
@@ -28,7 +28,8 @@ type imageCache struct {
absCacheDir string
pathSpec *helpers.PathSpec
mu sync.RWMutex
- store map[string]*Image
+
+ store map[string]*Image
}
func (c *imageCache) isInCache(key string) bool {
@@ -69,6 +70,11 @@ func (c *imageCache) getOrCreate(
}
// Now look in the file cache.
+ // Multiple Go routines can invoke same operation on the same image, so
+ // we need to make sure this is serialized per source image.
+ parent.createMu.Lock()
+ defer parent.createMu.Unlock()
+
cacheFilename := filepath.Join(c.absCacheDir, key)
// The definition of this counter is not that we have processed that amount