aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Pratt <mpratt@google.com>2022-06-03 16:22:58 -0400
committerMichael Pratt <mpratt@google.com>2022-06-09 18:17:45 +0000
commitc7ccabf3fea67f002bef190a5ffc7417f4371a23 (patch)
treeb65c92038821d560df2ba967bc97ef502f02c6b8
parent91019cc13d9de72d5e43a0068311dc9e6012777a (diff)
downloadgo-c7ccabf3fea67f002bef190a5ffc7417f4371a23.tar.gz
go-c7ccabf3fea67f002bef190a5ffc7417f4371a23.zip
runtime/cgo: retry _beginthread on EACCES
We occassionally see _beginthread failing with EACCES, meaning "insufficient resources" according to the Microsoft documentation. Exactly which resources is unclear. Similar to pthread_create on unix systems, we can wait a bit and retry to try to get success. The alternative is to abort, so we may as well give it a try. Fixes #52572. Change-Id: I6e05add53b4ae36c61e53b1ee3fed6bc74e17dfa Reviewed-on: https://go-review.googlesource.com/c/go/+/410355 Reviewed-by: Michael Knyszek <mknyszek@google.com> Reviewed-by: Ian Lance Taylor <iant@golang.org> Run-TryBot: Michael Pratt <mpratt@google.com> TryBot-Result: Gopher Robot <gobot@golang.org>
-rw-r--r--src/runtime/cgo/gcc_libinit_windows.c20
1 files changed, 16 insertions, 4 deletions
diff --git a/src/runtime/cgo/gcc_libinit_windows.c b/src/runtime/cgo/gcc_libinit_windows.c
index a9b94c3713..2b5896bb22 100644
--- a/src/runtime/cgo/gcc_libinit_windows.c
+++ b/src/runtime/cgo/gcc_libinit_windows.c
@@ -129,11 +129,23 @@ void (*(_cgo_get_context_function(void)))(struct context_arg*) {
}
void _cgo_beginthread(void (*func)(void*), void* arg) {
+ int tries;
uintptr_t thandle;
- thandle = _beginthread(func, 0, arg);
- if (thandle == -1) {
- fprintf(stderr, "runtime: failed to create new OS thread (%d)\n", errno);
- abort();
+ for (tries = 0; tries < 20; tries++) {
+ thandle = _beginthread(func, 0, arg);
+ if (thandle == -1 && errno == EACCES) {
+ // "Insufficient resources", try again in a bit.
+ //
+ // Note that the first Sleep(0) is a yield.
+ Sleep(tries); // milliseconds
+ continue;
+ } else if (thandle == -1) {
+ break;
+ }
+ return; // Success!
}
+
+ fprintf(stderr, "runtime: failed to create new OS thread (%d)\n", errno);
+ abort();
}