goprotocol-buffersmutex

Why do the Go-generated protobuf files contain mutex locks?


While working and generating protobuf stubs in go I stumbled upon this interesting issue.

Whenever I try and copy a message's struct by value I get this warning:

call of state.world.script.HandleEvent copies lock value: throne/server/messages.PlayerDialogeStatus contains google.golang.org/protobuf/internal/impl.MessageState contains sync.Mutex copylocks

While I understand why copying a mutex lock by value is wrong, I started wondering why are they even there in the first place.

And thus my question: Why does the go generated protobuf files contain mutex locks placed on the message structs, specifically on the MessageState struct?

Or alternatively: What is the goal of the mutex lock placed in the MessageState struct found on generated protobuf message structs?


Solution

  • The impl.MessageState is embedded in concrete messages only, not in the generated structs that implement a proto message.

    It specifically embeds the three pragmas: NoUnkeyedLiterals, DoNotCompare, and DoNotCopy.

    The last one, DoNotCopy is a zero-sized array of sync.Mutex. The sole purpose is to have go vet complain loudly about shallow copies, as described in the comment:

    DoNotCopy can be embedded in a struct to help prevent shallow copies. This does not rely on a Go language feature, but rather a special case within the vet checker.

    The summary of it all: impl.MessageState is not supposed to be copied and the mutex is there only to catch copying. If you do so, it is because you are using something the wrong way.