Awesome, thanks Jan for the fast and clear response.

In fact, the for {} is an infinite loop so wg.Wait() will never be reached 
and serve() will never terminate. Correct?

I guess I over-read how much this prototypical code was representative of a 
real server loop. Sorry Dave!

Tom

On Thursday, August 24, 2017 at 7:41:59 PM UTC+2, Jan Mercl wrote:
>
> No, wg.Add cannot "switch" to wg.Wait, they're both in the samr goroutine, 
> the go statement will be always the next one to execute after wg.Add within 
> serve().
>
> On Thu, Aug 24, 2017, 19:29 Tom Payne <twp...@gmail.com <javascript:>> 
> wrote:
>
>> I'm not singling out Dave Cheney here, I'd just like to check my 
>> understanding of Go's resource handling and concurrency.
>>
>> In this blog post a "prototypical network server" is presented:
>>
>>    https://dave.cheney.net/2017/08/20/context-isnt-for-cancellation
>>
>> Code:
>>
>> func serve(l net.Listener) error {
>>         var wg sync.WaitGroup
>>         var conn net.Conn
>>         var err error
>>         for {
>>                 conn, err = l.Accept()
>>                 if err != nil {
>>                         break
>>                 }
>>                 wg.Add(1)
>>                 go func(c net.Conn) {
>>                         defer wg.Done()
>>                         handle(c)
>>                 }(conn)
>>         }
>>         wg.Wait()
>>         return err
>> }
>>
>> My understanding is that this contains a race condition. Specifically, a 
>> goroutine switch can occur at the entry to wg.Add(1), switching to 
>> wg.Wait() in the main goroutine. At this point, a connection has been 
>> accepted, but the WaitGroup counter has not been incremented, so the serve 
>> function will terminate while silently dropping a network connection (the 
>> connection will be accepted, but never handled, so will probably eventually 
>> time out on the client side and leak a file descriptor on the server side).
>>
>> Is this understanding correct? Furthermore, I suspect that it's 
>> impossible to implement race-free graceful termination using only 
>> sync.WaitGroups. Is it actually possible to do so?
>>
>> Thanks for any correction, and apologies to Dave for picking on his code.
>>
>> Cheers,
>> Tom
>>
>> -- 
>> 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...@googlegroups.com <javascript:>.
>> For more options, visit https://groups.google.com/d/optout.
>>
> -- 
>
> -j
>

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