socket.go 中 SimpleQuery 中的本地互斥锁

local mutex in SimpleQuery in socket.go

我试图阅读mgo的代码,socket.go中的函数SimpleQuery令我困惑。在这个函数中,有两个本地互斥量: https://github.com/go-mgo/mgo/blob/v2-unstable/socket.go

func (socket *mongoSocket) SimpleQuery(op *queryOp) (data []byte, err error) {
    var wait, change sync.Mutex
    var replyDone bool
    var replyData []byte
    var replyErr error
    wait.Lock()
    op.replyFunc = func(err error, reply *replyOp, docNum int, docData []byte) {
        change.Lock()
        if !replyDone {
            replyDone = true
            replyErr = err
            if err == nil {
                replyData = docData
            }
        }
        change.Unlock()
        wait.Unlock()
    }
    err = socket.Query(op)
    if err != nil {
        return nil, err
    }
    wait.Lock()
    change.Lock()
    data = replyData
    err = replyErr
    change.Unlock()
    return data, err
}

据我了解,对于每个调用,都会有一个新的本地互斥锁,所以,它实际上是在保护任何东西,为什么他们把互斥锁放在这里?

他们正在将 SimpleQueryreplyFunc 同步。

  • wait用于等到replyFunc真正完成。
  • change用于锁定对replyDatareplyErr的访问。

互斥量正在保护数据结构,它们都在给定 replyFunc 回调的闭包中捕获。

wait 互斥锁阻塞,直到回调 returns,change 互斥锁保护 replyDatareplyErr 值。

添加那些的提交只说:

Make SimpleQuery race safe, irrespective of what the server does.

所以这可能是针对某些意外或遗留行为的额外保护,这就是为什么它使用多个互斥锁而不是单个原语来同步操作的原因。