diff options
author | Michael Pratt <mpratt@google.com> | 2022-06-03 16:22:58 -0400 |
---|---|---|
committer | Michael Pratt <mpratt@google.com> | 2022-06-09 18:17:45 +0000 |
commit | c7ccabf3fea67f002bef190a5ffc7417f4371a23 (patch) | |
tree | b65c92038821d560df2ba967bc97ef502f02c6b8 | |
parent | 91019cc13d9de72d5e43a0068311dc9e6012777a (diff) | |
download | go-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.c | 20 |
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(); } |