aboutsummaryrefslogtreecommitdiff
path: root/src/runtime/proc.go
diff options
context:
space:
mode:
authorBill Zissimopoulos <billziss@navimatics.com>2018-06-03 17:25:29 +0000
committerIan Lance Taylor <iant@golang.org>2018-06-05 13:50:06 +0000
commitbb0fae603bd19e096e38c3321d95bf114f40dcff (patch)
treeb0c45e56cf68249c65c4cdde293e640dcb5049f4 /src/runtime/proc.go
parent4a2bec9726eca30cd499695f210fe5e26f949229 (diff)
downloadgo-bb0fae603bd19e096e38c3321d95bf114f40dcff.tar.xz
runtime: handle windows callback on non-go thread
Adds an extra M in mstartm0 and accounts for it in checkdead. This allows Windows callbacks created with syscall.NewCallback and syscall.NewCallbackCDecl to be called on a non-Go thread. Fixes #6751 Change-Id: I57626bc009a6370b9ca0827ab64b14b01dec39d4 GitHub-Last-Rev: d429e3eed923640edab580bdb47fcb81e75dbfe8 GitHub-Pull-Request: golang/go#25575 Reviewed-on: https://go-review.googlesource.com/114802 Reviewed-by: Alex Brainman <alex.brainman@gmail.com> Reviewed-by: Ian Lance Taylor <iant@golang.org> Run-TryBot: Ian Lance Taylor <iant@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org>
Diffstat (limited to 'src/runtime/proc.go')
-rw-r--r--src/runtime/proc.go21
1 files changed, 18 insertions, 3 deletions
diff --git a/src/runtime/proc.go b/src/runtime/proc.go
index 9f4feebfd7..9908951544 100644
--- a/src/runtime/proc.go
+++ b/src/runtime/proc.go
@@ -1293,7 +1293,9 @@ func mstart1() {
//go:yeswritebarrierrec
func mstartm0() {
// Create an extra M for callbacks on threads not created by Go.
- if iscgo && !cgoHasExtraM {
+ // An extra M is also needed on Windows for callbacks created by
+ // syscall.NewCallback. See issue #6751 for details.
+ if (iscgo || GOOS == "windows") && !cgoHasExtraM {
cgoHasExtraM = true
newextram()
}
@@ -1618,8 +1620,12 @@ func allocm(_p_ *p, fn func()) *m {
// put the m back on the list.
//go:nosplit
func needm(x byte) {
- if iscgo && !cgoHasExtraM {
+ if (iscgo || GOOS == "windows") && !cgoHasExtraM {
// Can happen if C/C++ code calls Go from a global ctor.
+ // Can also happen on Windows if a global ctor uses a
+ // callback created by syscall.NewCallback. See issue #6751
+ // for details.
+ //
// Can not throw, because scheduler is not initialized yet.
write(2, unsafe.Pointer(&earlycgocallback[0]), int32(len(earlycgocallback)))
exit(1)
@@ -4215,8 +4221,17 @@ func checkdead() {
return
}
+ // If we are not running under cgo, but we have an extra M then account
+ // for it. (It is possible to have an extra M on Windows without cgo to
+ // accommodate callbacks created by syscall.NewCallback. See issue #6751
+ // for details.)
+ var run0 int32
+ if !iscgo && cgoHasExtraM {
+ run0 = 1
+ }
+
run := mcount() - sched.nmidle - sched.nmidlelocked - sched.nmsys
- if run > 0 {
+ if run > run0 {
return
}
if run < 0 {