Hi David,

Ah ha, magic. And all fixed. Sometimes another pair of eyes is all that
is required.
While I had no doubt the race detector was correct in reporting the
race the key line in the reply was "The only goroutine that can safely
close a channel is the one that is writing to it." After that
everything made sense and I could then see the other go routing calling
the close().

Anyhow updated, correct, and now simpler code is here:
https://play.golang.org/p/eUYLxQqcEr

Thanks

Owen


On Mon, 2017-04-24 at 13:10 -0700, dwah...@gmail.com wrote:
> Hi Owen,
> 
> > > > > > > > > > > > > > > > > > My understanding is that when a key is 
> > > > > > > > > > > > > > > > > > pressed that will terminate
the program. This closes the quit channel, which causes the
deferred closeChans() to be called. That in turn closes the done
and the bus channels in that order. Closing the done channel causes
the select in simBus() to complete in the <-done case. This causes
the bus channel to drain. The next call to writeToBus, which is
triggered by the timer going off - should then fail. The
cancelled() function should return true at this point so no attempt
should be made to write to the bus channel.
> > > > > > As I understand the data race below, this logic is flawed. Attempts
are being made to write to the bus channel after it has been
closed.
> > 
> > 
> > 
> > > > > > The race detector is correct. When you write "the next call to write
to us", you're making a faulty assumption -- namely, the assumption
that each call to writeToBus happens either before closeChans, or
after closeChans. But the two functions are called by separate
goroutines and can execute concurrently. So one can write to the bus
while the other is trying to close it, which is a race condition.
> 
> 
> 
> > > > (Similarly, when you write things like "Closing the done causes the
select in simBus() to complete, you should always remember that each
read from a channel happens *after* the corresponding write,
asynchronously, at a time which is not guaranteed.)
> 
> > > > This is a fundamental flaw with your approach. The only goroutine
that can safely close a channel is the one that is writing to it. So
your dataPump function needs to be the one to listen for the "quit"
signal.
> 
> Hope this helps!
> -- David
> 
> 
> 
> 
> 
> -- 
> 
> > 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.
> 

-- 
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.

Reply via email to