From 757cf4a6d1f069e032ea696b97e09f59128ebcc6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BE=90=E5=BF=97=E5=BC=BA?= Date: Wed, 18 Dec 2019 23:10:03 +0800 Subject: [PATCH] runtime: state more explicitly the behavior for buffered channels in the fast path under extreme conditions. This information can be useful when implement something like this: write side: eventCh := make(chan struct{}, 1) // buffer size of exactly 1 // something happened before (X) // notify via chan select { case eventCh <- struct{}{}: default: } read side: for { select { case <-eventCh: // new event comes, handle it } } This doc makes it explicit that right after `<-eventCh`, the `selectnbsend` in the write side is guaranteed to succeed. --- src/runtime/chan.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/runtime/chan.go b/src/runtime/chan.go index 677af99eac2dc3..76ad82636308f0 100644 --- a/src/runtime/chan.go +++ b/src/runtime/chan.go @@ -187,6 +187,9 @@ func chansend(c *hchan, ep unsafe.Pointer, block bool, callerpc uintptr) bool { // channel wasn't closed during the first observation. However, nothing here // guarantees forward progress. We rely on the side effects of lock release in // chanrecv() and closechan() to update this thread's view of c.closed and full(). + // + // After lock release in chanrecv() and closechan(), c.closed and full() is guaranteed to be observed here. + // For buffered channels, this fast path will always be false right after a successful chanrecv(). if !block && c.closed == 0 && full(c) { return false }