Closed zeldovich closed 5 years ago
I am not sure what you are talking about.
Can you reference some lines in code, and/or provide a reproducer?
Thanks.
Ah - I see it now. Thanks.
I was hoping to avoid using once.Do, but it has been streamlined to inline the fast path now, so I will use it. Fix coming soon.
basicHandle()
incodec/helper.go
uses an atomic compare-and-swap to ensure initialization gets called only once, but does not wait for initialization to finish, leading to a race condition.Suppose two goroutines use a shared
var h MsgpackHandle
and run code like this:Suppose further that the first goroutine to execute gets as far as
basicHandle
being called fromNewEncoderBytes
, and gets suspended right after its successful call toatomic.CompareAndSwapUint32
. Then the second goroutine will bypass this initialization logic, but will not get a fully-initialized handle (e.g.,x.be
is not yet set correctly). If the first goroutine now wakes up, its writes inbasicHandle
will now race with reads by the second goroutine.