Skip to content

Commit

Permalink
runtime/cgo: retry _beginthread on EACCES
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
prattmic committed Jun 9, 2022
1 parent 91019cc commit c7ccabf
Showing 1 changed file with 16 additions and 4 deletions.
20 changes: 16 additions & 4 deletions src/runtime/cgo/gcc_libinit_windows.c
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}

0 comments on commit c7ccabf

Please sign in to comment.