0

I have sharable object. Let's call it OBJ.

I wanted rarely update it. And to be able to read it frequently without locking.

I've tried this:

func Initialize() (func() func() OBJ, func()) {
    genFunc := func() func() OBJ {
        OBJ := getNewObject()
        secretFunc := func() OBJ {
            return OBJ
        }
        return secretFunc
    }
    secretFunc := genFunc()

    timer := time.NewTicker(time.Duration(timeoutSec) * time.Second)

    finish := make(chan bool)
    go func() {
        for {
            select {
            case <-finish:
                close(finish)
                return
            case <-timer.C:
                secretFunc = genFunc()
            }
        }
    }()

    retFunc := func() func() OBJ {
        return secretFunc
    }

    shutDownRet := func() {
        finish <- true
        timer.Stop()
    }
    return retFunc, shutDownRet
}

In this example, real sharable is not an OBJ, but function "secretFunc".

Is it thread/goroutine safe to do this trick with replacement of secretFunc without any locking? I would like to avoid using CAS & unsafe.Pointers.

If this is not safe, what is the pattern (if it exists) to implement this to be safe?

Jonathan Hall
  • 75,165
  • 16
  • 143
  • 189
Arkady
  • 2,084
  • 3
  • 27
  • 48
  • 1
    Like variables of other types, assignment to a function variable is not atomic. The code is not threadsafe if retFunc can be called concurrently with the assignment in the select. – Charlie Tumahai Oct 07 '18 at 16:35
  • As ThunderCat wrote, just because type of `secretFunc` is a function, it's no exception to the simple rule: if multiple goroutines access a variable concurrently, and at least one of the accesses is a write, then synchronization is required. – icza Oct 07 '18 at 19:04

0 Answers0