singleflight: avoid race between multiple Do calls

This is port of CL 436437, but without the test. ForgotUnshared has not
been ported here yet.

Change-Id: Id54d0c41d1a7948bf008e458c44b21670ada81e4
Reviewed-on: https://go-review.googlesource.com/c/sync/+/436495
Run-TryBot: Cuong Manh Le <cuong.manhle.vn@gmail.com>
Reviewed-by: Bryan Mills <bcmills@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Auto-Submit: Cuong Manh Le <cuong.manhle.vn@gmail.com>
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
diff --git a/singleflight/singleflight.go b/singleflight/singleflight.go
index 7c7fc50..8473fb7 100644
--- a/singleflight/singleflight.go
+++ b/singleflight/singleflight.go
@@ -144,9 +144,9 @@
 			c.err = errGoexit
 		}
 
-		c.wg.Done()
 		g.mu.Lock()
 		defer g.mu.Unlock()
+		c.wg.Done()
 		if g.m[key] == c {
 			delete(g.m, key)
 		}