]> Cypherpunks repositories - gostls13.git/commit
runtime: unlock OS thread after cgocallbackg1
authorCherry Mui <cherryyz@google.com>
Wed, 4 Oct 2023 14:21:39 +0000 (10:21 -0400)
committerCherry Mui <cherryyz@google.com>
Wed, 4 Oct 2023 16:36:59 +0000 (16:36 +0000)
commit68a12a80235fae67dc64fa2d232186a2e85c05f5
treef802e3b186a3cd29fad7ec6f1ebe575be696fa69
parent0c64ebce7e7007615aba58a19be07372f0febe69
runtime: unlock OS thread after cgocallbackg1

For cgo callbacks, currently cgocallbackg locks the OS thread and
then call cgocallbackg1, which invokes the actual callback, and
then unlocks the OS thread in a deferred call. cgocallback then
continues assuming we are on the same M. This assumes there is no
preemption point between the deferred unlockOSThread and returning
to the caller (cgocallbackg). But this is not always true. E.g.
when open defer is not used (e.g. PIE or shared build mode on 386),
there is a preemption point in deferreturn after invoking the
deferred function (when it checks whether there are still defers
to run).

Instead of relying on and requiring the defer implementation has
no preemption point, we move the unlockOSThread to the caller, and
ensuring no preemption by setting incgo to true before unlocking.
This doesn't cover the panicking path, so we also adds an
unlockOSThread there. There we don't need to worry about preemption,
because we're panicking out of the callback and we have unwound the
g0 stack, instead of reentering cgo.

Fixes #62102.

Change-Id: I0e0b9f9091be88d01675c0acb7339b81402545be
Reviewed-on: https://go-review.googlesource.com/c/go/+/532615
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Ian Lance Taylor <iant@google.com>
src/runtime/cgocall.go