golang的copyCheck.check如何检测对象复制?

How golang's copyCheck.check detect object copying?

// copyChecker holds back pointer to itself to detect object copying.
type copyChecker uintptr

func (c *copyChecker) check() {
    if uintptr(*c) != uintptr(unsafe.Pointer(c)) &&
        !atomic.CompareAndSwapUintptr((*uintptr)(c), 0, uintptr(unsafe.Pointer(c))) &&
        uintptr(*c) != uintptr(unsafe.Pointer(c)) {
        panic("sync.Cond is copied")
    }
}

When it's created, it sets its value to its own address. To check if it's been copied, it compares its address to the stored value. If it's been copied, its address will be different, but the value will be the same, so it will no longer be pointing to itself.

Okay, so, first look at what copyChecker is: It's a uintptr. So, there's a key point: The claim is that the thing must not be copied after first use. Every "use" (exported method) starts with invoking check on the object's checker. The first time you invoke one of the methods of the Cond type, it stashes the address of its checker. Any future use will check whether the checker object is at the stored address. If you copy it, the copy will have to have a different address, and this will panic.

How the actual check works:

The first time this gets hit, c is zero, so it's not the same as the address c is actually at. There's an atomic swap, which swaps in the address of c if and only if the current value is zero, and ensures that this happens atomically. The first comparison can suceed either if c is zero or if c has a value other than its own address. The compare ensures that it's not zero. Thus, when the third compare happens, either the value was zero and has since been set to its current address (and they will not be unequal), or the value wasn't zero in the first place. If the value wasn't zero, and is also not the same as the current address, that means that this Cond was made by taking a Cond which had already been used, and copying it to a new address.