On Thursday, 13 July 2017 04:56:25 UTC+1, Ian Lance Taylor wrote: > > On Wed, Jul 12, 2017 at 8:56 AM, James Abley <james...@gmail.com > <javascript:>> wrote: > > > > Labels for clarity: > > > > 1. goroutine 1 spawns goroutine 2 to read from Oregon, and spawns > goroutine > > 3 to read from Virginia. > > 2. goroutine 1 calls waitForSearchCompletion and enters the select. > Nothing > > can proceed, so that select blocks. > > 3. goroutine 3 completes Search and enters its select, sees that the > context > > isn't done, and sends on the respc channel > > 4. goroutine 1 can now proceed, by reading from the respc channel > > 5. goroutine 2 completes the Search and enters its select > > 6. ??? > > > > At this point, it seems as though goroutine 2 blocks if it uses a case, > and > > proceeds if it uses default. > > > > If it blocks (is it blocked by goroutine 1?), then goroutine 1 exits > from > > waitForSearchCompletion, and exits from Search, the deferred cancel() is > > evaluated, and the context is marked as done. The select in goroutine 2 > sees > > the context as Done and does not write to the channel. > > > > (I have never seen this version fail, having run soak tests that have > > exercised it for billions of iterations in a test application. It may be > a > > correct programme, or I may have been lucky so far). > > > > If it proceeds, then goroutine 2 is able to write to the channel (which > is > > never subsequently read, and thus leaks, and eventually starts failing > > hard). > > > > From https://golang.org/ref/spec#Send_statements > > > >> A send on an unbuffered channel can proceed if a receiver is ready > > > > When is the receiver respc ready for another write (by goroutine 2)? Is > the > > receiver ready after `case r := <-respc:` has been evaluated in > > waitForSearchCompletion? Does it need to wait until the StatementList of > the > > CommClause starts being run? Is it after that select exits? > > > > The thing that's confusing me is that the code in waitForSeachCompletion > > hasn't changed. I do not understand how I've changed the "readiness" of > the > > receiver. Presumably the choice of case or default is causing that? > > A send on an unbuffered channel is only ready when some other > goroutine reads from the channel. The sender will block until that > happens. > > In your program, when goroutine 1 gets an answer and writes to the > channel, waitForSearchCompletion reads the value and returns. At that > point nothing ever reads from respc. So when goroutine 2 tries to > write to respc, it blocks waiting for a reader that never appears. > > Ian >
Oh, that's what I hadn't understood. Thank you for your help, and your patience. -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.