Several sources, including this issue comment:

https://github.com/golang/go/issues/27544#issuecomment-419265234

state that a buffered channel of size 1 can be used as a trylock by 
select'ing on it with a default case.

I was thinking about it and it seemed to me that with such an 
implementation, it is unclear whether a failed acquisition of the trylock 
guarantees that the lock is held by someone else. More precisely, I can't 
tell if the following guarantee holds: a failed acquisition of the trylock 
cannot happen-before a successful acquisition, unless a release 
happens-between them. (To put it another way: can there be "spurious" 
failures of trylock acquisition?)

In particular:

1. The memory model documentation states ordering guarantees for 
*successful* channel receives and sends, but doesn't say anything about 
failed nonblocking receives and sends, so it seems to me that in principle 
it can't be promising anything about this behavior.

2. I can't tell whether the fast-path checks in the current implementation 
allow for this:

https://github.com/golang/go/blob/919594830f17f25c9e971934d825615463ad8a10/src/runtime/chan.go#L159
https://github.com/golang/go/blob/919594830f17f25c9e971934d825615463ad8a10/src/runtime/chan.go#L437

In particular, I don't understand why `chanrecv` does an atomic read of 
`qcount`, but `chansend` just does a normal read.

One case where this is relevant is implementing something like a write-back 
cache with at most one goroutine performing the writeback:

func update() {
    mark_state_dirty()
    if trylock.TryAcquire() {
        go writeback_worker()
    } // else: some writeback worker is guaranteed to be active
}

func writeback_worker() {
    for {
        perform_writeback()
        trylock.Release()
        if !state_is_dirty() {
            return // nothing more to do
        }
        if !trylock.TryAcquire() {
            return // a new writeback worker is guaranteed to be active
        } // else: loop back around and do the writeback again
    }
}

where, in the absence of this guarantee, an update can be "missed" and 
writeback can be delayed arbitrarily.

Thanks very much for your time.

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/895d7cc7-5664-45e3-bf94-85be853fffdf%40googlegroups.com.

Reply via email to