counter := intr64(N)
release := make(chan struct{})
...
for i := 0; i < N; i ++ {
h.Handle(func() {
<-release
atomic.AddInt64(&counter, -1)
})
}
...
go func(){
time.Sleep(time.Millisecond) // so we would certainly hit h.Close,
before we continue
for i := 0; i < N; i++ { release <- struct{}{};
time.Sleep(time.Millisecond) }
// alternatively use runtime.Gosched() instead of Sleep
}()
h.Close()
if atomic.LoadInt64(&counter) > 0 {
// fail
}
It's not completely fool-proof, but should work well enough in practice.
On Tuesday, 13 September 2016 21:56:08 UTC+3, Evan Digby wrote:
>
> Has anyone come across a good way, non-racy way to ensure that N tasks are
> guaranteed to be completed after a function is called? Essentially I have a
> “Close” function that must be guaranteed to block until all tasks are
> finished. Achieving this was pretty simple: wrap each task in an RLock, and
> then a Lock on close.
>
> Example: https://play.golang.org/p/7lhBPUhkUE
>
> Now I want to write a solid test to guarantee Close will meet that
> requirement of all tasks must finish first for posterity. In that example,
> try commenting out the RLock/RUnlock on lines 25/26. You'll see that it no
> longer outputs many, if any, lines. I'm trying to prevent that from
> happening in the future by some cowboy refactor!
>
> All of the ways I can come up with involve Sleeping or launching more
> tasks than I _think_ can be finished in time--obviously not good!
>
> I feel like I must be missing some obvious way to test this and I'll end
> up feeling silly once someone replies with the solution. I'm okay with that!
>
--
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 [email protected].
For more options, visit https://groups.google.com/d/optout.