diff --git a/src/common.c b/src/common.c index ea5e472..f1a0be3 100644 --- a/src/common.c +++ b/src/common.c @@ -182,7 +182,7 @@ int timeouts[12] = { EINVAL below it and the thread silently gets the 8M system default stack. */ size_t threadstacksize(int extra){ - long size = BASESTACKSIZE + extra; + long size = BASESTACKSIZE + TLSSTACKSIZE + extra; if(size < (long)PTHREAD_STACK_MIN) size = (long)PTHREAD_STACK_MIN; return (size_t)size; diff --git a/src/conf.c b/src/conf.c index fc74b22..7486185 100644 --- a/src/conf.c +++ b/src/conf.c @@ -158,7 +158,12 @@ int start_proxy_thread(struct child * chp){ pthread_attr_init(&pa); pthread_attr_setstacksize(&pa,threadstacksize(conf.stacksize)); pthread_attr_setdetachstate(&pa,PTHREAD_CREATE_DETACHED); - pthread_create(&thread, &pa, startsrv, (void *)chp); + if(pthread_create(&thread, &pa, startsrv, (void *)chp)){ + pthread_attr_destroy(&pa); + fprintf(stderr, "Failed to create service thread on line %d, try to set larger stacksize\n", linenum); + _3proxy_sem_unlock(conf.threadinit); + return(40); + } pthread_attr_destroy(&pa); #endif _3proxy_sem_lock(conf.threadinit); diff --git a/src/proxy.h b/src/proxy.h index 7a65f75..87d405d 100644 --- a/src/proxy.h +++ b/src/proxy.h @@ -135,6 +135,23 @@ void daemonize(void); #endif #endif +/* wolfSSL reserves around 48K of static thread-local storage. glibc counts + that against the thread stack, so pthread_create() fails with EINVAL and + no thread starts at all. musl places the block next to the stack instead + of inside it and needs nothing extra, and OpenSSL has no static TLS. + musl identifies itself by no macro of its own, but it does not define + __GLIBC__, which any libc header pulled in above would have set. + */ +#ifndef TLSSTACKSIZE +#if defined(__linux__) && !defined(__GLIBC__) +#define TLSSTACKSIZE 0 +#elif defined(WITH_WOLFSSL) +#define TLSSTACKSIZE 49152 +#else +#define TLSSTACKSIZE 0 +#endif +#endif + #ifndef _WIN32 size_t threadstacksize(int extra); #endif