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:
parent
9b6244c6c2
commit
d6dd5b4d4f
1 changed files with 30 additions and 42 deletions
|
@ -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);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue