From 75c5916ddef8987e853992483493af7088d05040 Mon Sep 17 00:00:00 2001 From: Stephen J Day Date: Thu, 8 Jan 2015 12:03:21 -0800 Subject: [PATCH] Release lock during WriteStream for inmemory driver While reading from the input in WriteStream, the inmemory driver can deadlock if the reader is from the same instance. To fix this, the write lock is released before reading into a local buffer. The lock is re-acquired to finish the actual write. Signed-off-by: Stephen J Day --- storagedriver/inmemory/driver.go | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/storagedriver/inmemory/driver.go b/storagedriver/inmemory/driver.go index e3c63f741..c2be1913b 100644 --- a/storagedriver/inmemory/driver.go +++ b/storagedriver/inmemory/driver.go @@ -133,6 +133,11 @@ func (d *Driver) WriteStream(path string, offset int64, reader io.Reader) (nn in return 0, fmt.Errorf("not a file") } + // Unlock while we are reading from the source, in case we are reading + // from the same mfs instance. This can be fixed by a more granular + // locking model. + d.mutex.Unlock() + d.mutex.RLock() // Take the readlock to block other writers. var buf bytes.Buffer nn, err = buf.ReadFrom(reader) @@ -142,9 +147,13 @@ func (d *Driver) WriteStream(path string, offset int64, reader io.Reader) (nn in // backend. What is the correct return value? Really, the caller needs // to know that the reader has been advanced and reattempting the // operation is incorrect. + d.mutex.RUnlock() + d.mutex.Lock() return nn, err } + d.mutex.RUnlock() + d.mutex.Lock() f.WriteAt(buf.Bytes(), offset) return nn, err }