I've been tempted to reset the sync.Once inside the function, but I believe 
there's a subtle bug -- I'd be very interested to know if my understanding 
is incorrect.

When Do() is called for the first time, it can aquire a mutex, and defers 
the unlocking until after the supplied function has completed.  If you 
reset the state of the Once inside the supplied function, the mutex state 
gets reset as well -- meaning that the defer would unlock a mutex that 
hadn't ever been locked.

Calling the Do() *again* with in the supplied function is...asking for more 
problems, and starts getting a bit harder to reason about than I care to 
try on a sunday evening.

It'd be much better to use something 
like https://godoc.org/golang.org/x/sync/singleflight  to deduplicate calls 
-- or have a secondary mutex that gets aquired to occasionally reset the 
once.

On Sunday, November 19, 2017 at 4:24:41 PM UTC-8, Carl Mastrangelo wrote:
>
> Hi gophers,
>
> I was playing around with a puzzle trying to break the sync package and 
> found something cool.   Can you think of a definition for f that causes 
> once.Do to execute the argument more than once?
>
>
> package main
>
> import (
>     "sync"
> )
>
> func main() {
>     var once sync.Once
>     var f = // ...
>
>     once.Do(f)
> }
>
>
> HIGHLIGHT BELOW FOR ANSWER
>
>
> package main
>
> import (
>     "fmt"
>     "sync"
> )
>
> func main() {
>     var once sync.Once
>     var f func()
>     times := 9
>     f = func() {
>         if times == 0 {
>             return
>         }
>         times--
>         fmt.Println("Called")
>         oldonce := once
>         *&once = sync.Once{}
>         once.Do(f)
>         once = oldonce
>
>     }
>     once.Do(f)
> }
>
> HIGHLIGHT ABOVE FOR ANSWER
>

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