1
0
Fork 0
mirror of https://github.com/luanti-org/luanti.git synced 2025-08-11 17:51:04 +00:00

make timeout behaviour consistent

This commit is contained in:
Desour 2024-10-05 12:01:04 +02:00
parent 9b6244c6c2
commit d6dd5b4d4f

View file

@ -20,6 +20,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "ipc_channel.h" #include "ipc_channel.h"
#include "debug.h" #include "debug.h"
#include "porting.h"
#include <cerrno> #include <cerrno>
#include <utility> #include <utility>
#include <cstring> #include <cstring>
@ -193,17 +194,34 @@ static void post(IPCChannelBuffer *buf) noexcept
#endif #endif
static bool wait_in(IPCChannelEnd::Dir *dir, int timeout_ms, u64 t0)
{
#if defined(IPC_CHANNEL_IMPLEMENTATION_WIN32) #if defined(IPC_CHANNEL_IMPLEMENTATION_WIN32)
static bool wait_in(IPCChannelEnd::Dir *dir, DWORD timeout) DWORD timeout = INFINITE;
{ if (timeout_ms >= 0) {
timeout = (DWORD)timeout_ms;
timeout_msu -= porting::getTimeMs() - t0; // Relative time
}
return wait(dir->sem_in, timeout); return wait(dir->sem_in, timeout);
}
#else #else
static bool wait_in(IPCChannelEnd::Dir *dir, const struct timespec *timeout) struct timespec timeout;
{ struct timespec *timeoutp = nullptr;
return wait(dir->buf_in, timeout); if (timeout_ms >= 0) {
} u64 timeout_msu = timeout_ms;
#if defined(IPC_CHANNEL_IMPLEMENTATION_LINUX_FUTEX)
timeout_msu -= porting::getTimeMs() - t0; // Relative time
#elif defined(IPC_CHANNEL_IMPLEMENTATION_POSIX)
timeout_msu += t0; // Absolute time
#endif #endif
timeout.tv_sec = timeout_msu / 1000;
timeout.tv_nsec = timeout_msu % 1000 * 1000000UL;
timeoutp = &timeout;
}
return wait(dir->buf_in, timeoutp);
#endif
}
static void post_out(IPCChannelEnd::Dir *dir) static void post_out(IPCChannelEnd::Dir *dir)
{ {
@ -214,26 +232,6 @@ static void post_out(IPCChannelEnd::Dir *dir)
#endif #endif
} }
#if defined(IPC_CHANNEL_IMPLEMENTATION_WIN32)
static DWORD get_timeout(int timeout_ms)
{
return timeout_ms < 0 ? INFINITE : (DWORD)timeout_ms;
}
#elif defined(IPC_CHANNEL_IMPLEMENTATION_LINUX_FUTEX) || defined(IPC_CHANNEL_IMPLEMENTATION_POSIX)
static struct timespec *set_timespec(struct timespec *ts, int ms)
{
if (ms < 0)
return nullptr;
u64 msu = ms;
#if defined(IPC_CHANNEL_IMPLEMENTATION_POSIX)
msu += porting::getTimeMs(); // Absolute time
#endif
ts->tv_sec = msu / 1000;
ts->tv_nsec = msu % 1000 * 1000000UL;
return ts;
}
#endif
template <typename T> template <typename T>
static inline void write_once(volatile T *var, const T val) static inline void write_once(volatile T *var, const T val)
{ {
@ -280,17 +278,12 @@ void IPCChannelEnd::sendSmall(const void *data, size_t size) noexcept
bool IPCChannelEnd::sendLarge(const void *data, size_t size, int timeout_ms) noexcept bool IPCChannelEnd::sendLarge(const void *data, size_t size, int timeout_ms) noexcept
{ {
#if defined(IPC_CHANNEL_IMPLEMENTATION_WIN32) u64 t0 = porting::getTimeMs();
DWORD timeout = get_timeout(timeout_ms);
#else
struct timespec timeout_s;
struct timespec *timeout = set_timespec(&timeout_s, timeout_ms);
#endif
write_once(&m_dir.buf_out->size, size); write_once(&m_dir.buf_out->size, size);
do { do {
memcpy(m_dir.buf_out->data, data, IPC_CHANNEL_MSG_SIZE); memcpy(m_dir.buf_out->data, data, IPC_CHANNEL_MSG_SIZE);
post_out(&m_dir); post_out(&m_dir);
if (!wait_in(&m_dir, timeout)) // TODO: always relative timeout, or always absolute if (!wait_in(&m_dir, timeout_ms, t0))
return false; return false;
size -= IPC_CHANNEL_MSG_SIZE; size -= IPC_CHANNEL_MSG_SIZE;
data = (u8 *)data + IPC_CHANNEL_MSG_SIZE; data = (u8 *)data + IPC_CHANNEL_MSG_SIZE;
@ -303,13 +296,8 @@ bool IPCChannelEnd::sendLarge(const void *data, size_t size, int timeout_ms) noe
bool IPCChannelEnd::recvWithTimeout(int timeout_ms) noexcept bool IPCChannelEnd::recvWithTimeout(int timeout_ms) noexcept
{ {
#if defined(IPC_CHANNEL_IMPLEMENTATION_WIN32) u64 t0 = porting::getTimeMs();
DWORD timeout = get_timeout(timeout_ms); if (!wait_in(&m_dir, timeout_ms, t0))
#else
struct timespec timeout_s;
struct timespec *timeout = set_timespec(&timeout_s, timeout_ms);
#endif
if (!wait_in(&m_dir, timeout))
return false; return false;
size_t size = read_once(&m_dir.buf_in->size); size_t size = read_once(&m_dir.buf_in->size);
m_recv_size = size; m_recv_size = size;
@ -336,7 +324,7 @@ bool IPCChannelEnd::recvWithTimeout(int timeout_ms) noexcept
size -= IPC_CHANNEL_MSG_SIZE; size -= IPC_CHANNEL_MSG_SIZE;
recv_data += IPC_CHANNEL_MSG_SIZE; recv_data += IPC_CHANNEL_MSG_SIZE;
post_out(&m_dir); post_out(&m_dir);
if (!wait_in(&m_dir, timeout)) if (!wait_in(&m_dir, timeout_ms, t0))
return false; return false;
} while (size > IPC_CHANNEL_MSG_SIZE); } while (size > IPC_CHANNEL_MSG_SIZE);
memcpy(recv_data, m_dir.buf_in->data, size); memcpy(recv_data, m_dir.buf_in->data, size);