]> Cypherpunks repositories - gostls13.git/commitdiff
doc: race condition in unsynchronized send/close
authorChangkun Ou <hi@changkun.us>
Sun, 16 Feb 2020 00:11:53 +0000 (01:11 +0100)
committerRob Pike <r@golang.org>
Mon, 2 Mar 2020 08:42:10 +0000 (08:42 +0000)
This CL documents that unsynchronized send and close operations
on a channel are detected as a race condition.

Fixes #27769

Change-Id: I7495a2d0dd834c3f3b6339f8ca18ea21ae979aa8
Reviewed-on: https://go-review.googlesource.com/c/go/+/219637
Reviewed-by: Rob Pike <r@golang.org>
doc/articles/race_detector.html

index 014411d9484c1e23c2396600c8a47ffff1a5cd68..63a658f870bcc3f415e449c4c7587e5fc56cc620 100644 (file)
@@ -379,6 +379,38 @@ func (w *Watchdog) Start() {
 }
 </pre>
 
+<h3 id="Unsynchronized_send_and_close_operations">Unsynchronized send and close operations</h3>
+
+<p>
+As this example demonstrates, unsynchronized send and close operations
+on the same channel can also be a race condition:
+</p>
+
+<pre>
+c := make(chan struct{}) // or buffered channel
+
+// The race detector cannot derive the happens before relation
+// for the following send and close operations. These two operations
+// are unsynchronized and happen concurrently.
+go func() { c <- struct{}{} }()
+close(c)
+</pre>
+
+<p>
+According to the Go memory model, a send on a channel happens before
+the corresponding receive from that channel completes. To synchronize
+send and close operations, use a receive operation that guarantees
+the send is done before the close:
+</p>
+
+<pre>
+c := make(chan struct{}) // or buffered channel
+
+go func() { c <- struct{}{} }()
+<-c
+close(c)
+</pre>
+
 <h2 id="Supported_Systems">Supported Systems</h2>
 
 <p>