summaryrefslogtreecommitdiff
path: root/ext/socket
diff options
context:
space:
mode:
authorYusuke Endoh <mame@ruby-lang.org>2023-11-28 20:46:00 +0900
committerYusuke Endoh <mame@ruby-lang.org>2023-11-28 20:49:12 +0900
commit62c816410ff5e1d54da3ff3819ec1c67489066ff (patch)
tree2cff1125d5fca2d0e08b524eaa95d25713505eb1 /ext/socket
parent1a16b6ffc2d48b93c730cd6e57fac6a68fa05737 (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.c18
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;
}