diff options
author | Yusuke Endoh <mame@ruby-lang.org> | 2023-11-28 20:46:00 +0900 |
---|---|---|
committer | Yusuke Endoh <mame@ruby-lang.org> | 2023-11-28 20:49:12 +0900 |
commit | 62c816410ff5e1d54da3ff3819ec1c67489066ff (patch) | |
tree | 2cff1125d5fca2d0e08b524eaa95d25713505eb1 /ext/socket | |
parent | 1a16b6ffc2d48b93c730cd6e57fac6a68fa05737 (diff) |
Retry pthread_create a few times
According to https://bugs.openjdk.org/browse/JDK-8268605, pthread_create
may fail spuriously. This change implements a simple retry as a modest
measure, which is also used by JDK.
Diffstat (limited to 'ext/socket')
-rw-r--r-- | ext/socket/raddrinfo.c | 18 |
1 files changed, 16 insertions, 2 deletions
diff --git a/ext/socket/raddrinfo.c b/ext/socket/raddrinfo.c index 18585c2181..78c94defc5 100644 --- a/ext/socket/raddrinfo.c +++ b/ext/socket/raddrinfo.c @@ -461,6 +461,20 @@ cancel_getaddrinfo(void *ptr) } static int +do_pthread_create(pthread_t *th, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg) +{ + int limit = 3, ret; + do { + // It is said that pthread_create may fail spuriously, so we follow the JDK and retry several times. + // + // https://bugs.openjdk.org/browse/JDK-8268605 + // https://github.com/openjdk/jdk/commit/e35005d5ce383ddd108096a3079b17cb0bcf76f1 + ret = pthread_create(th, attr, start_routine, arg); + } while (ret == EAGAIN && limit-- > 0); + return ret; +} + +static int rb_getaddrinfo(const char *hostp, const char *portp, const struct addrinfo *hints, struct addrinfo **ai) { int retry; @@ -491,7 +505,7 @@ start: #endif pthread_t th; - if (pthread_create(&th, &attr, do_getaddrinfo, arg) != 0) { + if (do_pthread_create(&th, &attr, do_getaddrinfo, arg) != 0) { free_getaddrinfo_arg(arg); return EAI_AGAIN; } @@ -718,7 +732,7 @@ start: #endif pthread_t th; - if (pthread_create(&th, 0, do_getnameinfo, arg) != 0) { + if (do_pthread_create(&th, 0, do_getnameinfo, arg) != 0) { free_getnameinfo_arg(arg); return EAI_AGAIN; } |