Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

I think you are wrong in thinking he is protecting the `triggered` variable with the lock. He's using a Mutex to synchronize access on the entire struct.

snippet from https://github.com/Workiva/go-datastructures/blob/master/fut...

    f.lock.Lock()
    f.triggered = true
    f.item = item
    f.err = err
    f.lock.Unlock()
    f.wg.Done()


I'm confident the following is identical (if nothing else about the code changes). Notice how access to `f.item` and `f.err` aren't read protected in `GetResult`.

    func (f *Future) setItem(item interface{}, err error) {
	f.item = item
	f.err = err
        f.lock.Lock()
        f.triggered = true
	f.lock.Unlock()
	f.wg.Done()
    }
Any reader of `f.item` or `f.err` (in `GetResult`) is essentially waiting for triggered to be true before reading the value of those respective fields. If after an atomic load or synchronized access of triggered returns `true`, both versions of `setItem` should guarantee that a subsequent read of `f.item` will return the "promised" value.

In any case, because the reads (in `GetResult`) aren't protected as well, and the call to `setItem` which writes to `item` and `err` only happens on a single thread, the only thing the code perfectly protects now are reads of triggered.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: