On Tue, Mar 25, 2014 at 3:11 PM, Péter Szilágyi <
pet...@gmail.com> wrote:
>
> On Tue, Mar 25, 2014 at 1:03 PM, Dmitry Vyukov <
dvy...@google.com> wrote:
>>
>> I do not see how this can possibly work:
>>
>> // Inserts a state exchange into the exchange queue
>> func (o *Overlay) exch(p *peer, s *state) {
>> // Insert the state exchange
>> o.eventPend.Add(1)
>> o.eventLock.Lock()
>> o.exchSet[p] = s
>> o.eventLock.Unlock()
>> o.eventPend.Done()
>>
>>
>> You do Add and Done at the same instant in time.
>> If o.eventPend.Wait is called before o.exch, then there is indeed a
>> race -- Wait won't wait for Add.
>
> Yes, but in my case that is not a problem, since I don't call Wait only a
> single time, but in a loop. The add will be caught by the next wait
> invocation.
>
>>
>> If o.eventPend.Wait is called after o.exch, then Add/Done are
>> senseless -- the sum of Add/Done is zero.
I believe this is incorrect usage of WaitGroup. The counter must not
be incremented from zero while a goroutine is in wg.Wait.
Future wg implementations can break your code.
> The point of add and done is wait until all concurrent go routines currently
> *inside* o.exch to finish. For example I receive 10 state updates. I want
> all 10 to be inserted into o.exchSet before allowing it to be swapped out by
> my manager. In the mean time more updates can arrive, it's not a problem,
> they will be processed in the next iteration.
This looks like a very very weak (close to senseless) aggregation
strategy to me. The region between Add and Done can be executed in
100ns. So even if 10 updates have arrived almost simultaneously, you
still can have 10 separate updates.
See my previous email with a much stronger aggregation strategy,
basically the updater collects all updates in a given time window
after the first update.