diff --git a/src/threading/ipc_channel.cpp b/src/threading/ipc_channel.cpp index 4b0f37a54..1cfd07412 100644 --- a/src/threading/ipc_channel.cpp +++ b/src/threading/ipc_channel.cpp @@ -128,20 +128,35 @@ static void post(IPCChannelBuffer *buf) noexcept // timeout is absolute (using cond_clockid) // returns false on timeout -static bool wait(IPCChannelBuffer *buf, const struct timespec *timeout) noexcept +static bool wait(IPCChannelBuffer *buf, const struct timespec *timeout, const char *timestr = nullptr) noexcept { + if (timestr) + errorstream << timestr << std::endl; + bool timed_out = false; pthread_mutex_lock(&buf->mutex); while (!buf->posted) { if (timeout) { - if (pthread_cond_timedwait(&buf->cond, &buf->mutex, timeout) == ETIMEDOUT) - return false; + auto err = pthread_cond_timedwait(&buf->cond, &buf->mutex, timeout); + if (err == ETIMEDOUT) { + timed_out = true; + break; + } else if (err == EINTR || err == EOWNERDEAD || err == ENOTRECOVERABLE || err == EPERM || err == EINVAL) { + continue; + } else if (err != 0) { + pthread_mutex_unlock(&buf->mutex); + auto msg = "err: " + std::to_string(err); + FATAL_ERROR(msg.c_str()); + bool ret = wait(buf, timeout, msg.c_str()); + errorstream << msg << std::endl; + return ret; + } } else { pthread_cond_wait(&buf->cond, &buf->mutex); } } buf->posted = false; pthread_mutex_unlock(&buf->mutex); - return true; + return !timed_out; } static void post(IPCChannelBuffer *buf) noexcept @@ -172,6 +187,8 @@ static bool wait_in(IPCChannelEnd::Dir *dir, u64 timeout_ms_abs) #else struct timespec timeout; struct timespec *timeoutp = nullptr; + char timestr[201]; + timestr[0] = '\0'; if (timeout_ms_abs > 0) { u64 tnow = porting::getTimeMs(); if (tnow > timeout_ms_abs) @@ -182,21 +199,26 @@ static bool wait_in(IPCChannelEnd::Dir *dir, u64 timeout_ms_abs) timeout.tv_sec = 0; timeout.tv_nsec = 0; #elif defined(IPC_CHANNEL_IMPLEMENTATION_POSIX) - // Absolute time, relative to cond_clockid - FATAL_ERROR_IF(clock_gettime(dir->buf_in->cond_clockid, &timeout) < 0, + // Absolute time + FATAL_ERROR_IF(clock_gettime(CLOCK_REALTIME, &timeout) < 0, "clock_gettime failed"); - // prevent overflow +#endif + timeout.tv_sec += timeout_ms_rel / 1000; + timeout.tv_nsec += timeout_ms_rel % 1000 * 1000'000L; + // tv_nsec must be smaller than 1 sec, or else pthread_cond_timedwait fails if (timeout.tv_nsec >= 1000'000'000L) { timeout.tv_nsec -= 1000'000'000L; timeout.tv_sec += 1; } -#endif - timeout.tv_sec += timeout_ms_rel / 1000; - timeout.tv_nsec += timeout_ms_rel % 1000 * 1000'000L; timeoutp = &timeout; + + time_t timeout_tt = timeout.tv_sec + timeout.tv_nsec / 1000'000'000L; + tm timeout_tm; + localtime_r(&timeout_tt, &timeout_tm); + strftime(timestr, 200, "%F %T ", &timeout_tm); } - return wait(dir->buf_in, timeoutp); + return wait(dir->buf_in, timeoutp, timestr); #endif } @@ -226,6 +248,7 @@ IPCChannelBuffer::IPCChannelBuffer() #if defined(IPC_CHANNEL_IMPLEMENTATION_POSIX) pthread_condattr_t condattr; pthread_mutexattr_t mutexattr; + clockid_t cond_clockid; if (pthread_condattr_init(&condattr) != 0) goto error_condattr_init; if (pthread_mutexattr_init(&mutexattr) != 0) @@ -242,6 +265,12 @@ IPCChannelBuffer::IPCChannelBuffer() goto error_mutex_init; pthread_mutexattr_destroy(&mutexattr); pthread_condattr_destroy(&condattr); +/* + { + std::string bla = std::string("realt: ") + std::to_string(CLOCK_REALTIME) + " cond_clockid: " + std::to_string(cond_clockid); + FATAL_ERROR(bla.c_str()); + }*/ + FATAL_ERROR_IF(cond_clockid != CLOCK_REALTIME, "wrong clock"); return; error_mutex_init: @@ -350,7 +379,7 @@ bool IPCChannelEnd::recvWithTimeout(int timeout_ms) noexcept m_large_recv.resize(size); } catch (...) { // it's ok for us if an attacker wants to make us abort - std::string errmsg = std::string("std::vector::resize failed, size was: ") + std::string errmsg = "std::vector::resize failed, size was: " + std::to_string(size); FATAL_ERROR(errmsg.c_str()); } diff --git a/src/threading/ipc_channel.h b/src/threading/ipc_channel.h index 09acd09ec..eafc2c2a6 100644 --- a/src/threading/ipc_channel.h +++ b/src/threading/ipc_channel.h @@ -30,7 +30,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #if defined(_WIN32) #define IPC_CHANNEL_IMPLEMENTATION_WIN32 -#elif defined(__linux__) +#elif defined(__linux__) && 0 #define IPC_CHANNEL_IMPLEMENTATION_LINUX_FUTEX #else #define IPC_CHANNEL_IMPLEMENTATION_POSIX @@ -71,7 +71,6 @@ struct IPCChannelBuffer #elif defined(IPC_CHANNEL_IMPLEMENTATION_POSIX) pthread_cond_t cond; - clockid_t cond_clockid; pthread_mutex_t mutex; bool posted = false; // protected by mutex #endif