diff --git a/server/main.cpp b/server/main.cpp index 112af8c..4c88bc5 100644 --- a/server/main.cpp +++ b/server/main.cpp @@ -1,3 +1,4 @@ +#include #include #include #include @@ -438,4 +439,33 @@ int main(int argc, char** argv) { terminal::uninstall(); mainThreadDone = true; return 0; +} + +/* Fix for Virtuzzo 7 where sometimes the pthread create fails! */ + +typedef int (*pthread_create_t)(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg); +pthread_create_t original_pthread_create{nullptr}; +int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg) { + if(!original_pthread_create) { + original_pthread_create = (pthread_create_t) dlsym(RTLD_NEXT, "pthread_create"); + if(!original_pthread_create) { + std::cerr << "[CRITICAL] Missing original pthread_create function. Aborting execution!" << std::endl; + std::abort(); + } + } + + int result, attempt{0}; + while((result = original_pthread_create(thread, attr, start_routine, arg)) != 0 && errno == EAGAIN) { + if(attempt > 10) { + std::cerr << "[CRITICAL] pthread_create(...) cause EAGAIN for the last 10 attempts! Aborting application execution!" << std::endl; + std::abort(); + } else if(attempt > 5) { + /* let some other threads do work */ + pthread_yield(); + } + std::cerr << "[CRITICAL] pthread_create(...) cause EAGAIN! Trying again in 5usec (Attempt: " << attempt << ")" << std::endl; + usleep(5); + attempt++; + } + return result; } \ No newline at end of file