diff options
| author | Dmitry Vyukov <dvyukov@google.com> | 2019-01-31 09:44:35 +0100 |
|---|---|---|
| committer | Dmitry Vyukov <dvyukov@google.com> | 2019-01-31 11:35:53 +0100 |
| commit | 6fb60a48131bd6ca2bb8ea760f253e057547c429 (patch) | |
| tree | 4259ab876f074c1ee9d1876be07b8ef62de41356 /executor | |
| parent | 7e81a532301ad5caef5158226cef3a11898987c9 (diff) | |
executor: handle pthread_create errors better
See the added comment for explanation.
Diffstat (limited to 'executor')
| -rw-r--r-- | executor/common.h | 19 |
1 files changed, 16 insertions, 3 deletions
diff --git a/executor/common.h b/executor/common.h index 6f11ef058..61600a712 100644 --- a/executor/common.h +++ b/executor/common.h @@ -241,9 +241,22 @@ static void thread_start(void* (*fn)(void*), void* arg) pthread_attr_t attr; pthread_attr_init(&attr); pthread_attr_setstacksize(&attr, 128 << 10); - if (pthread_create(&th, &attr, fn, arg)) - exitf("pthread_create failed"); - pthread_attr_destroy(&attr); + int i; + // Clone can fail spuriously with EAGAIN if there is a concurrent execve in progress. + // (see linux kernel commit 498052bba55ec). But it can also be a true limit imposed by cgroups. + // In one case we want to retry infinitely, in another -- fail immidiately... + for (i = 0; i < 100; i++) { + if (pthread_create(&th, &attr, fn, arg) == 0) { + pthread_attr_destroy(&attr); + return; + } + if (errno == EAGAIN) { + usleep(50); + continue; + } + break; + } + exitf("pthread_create failed"); } #endif |
