diff --git a/src/threading/ipc_channel.cpp b/src/threading/ipc_channel.cpp index 30460a650..e2ed45637 100644 --- a/src/threading/ipc_channel.cpp +++ b/src/threading/ipc_channel.cpp @@ -284,7 +284,7 @@ bool IPCChannelEnd::sendLarge(const void *data, size_t size, int timeout_ms) noe return true; } -bool IPCChannelEnd::recv(int timeout_ms) noexcept +bool IPCChannelEnd::recvWithTimeout(int timeout_ms) noexcept { #if defined(IPC_CHANNEL_IMPLEMENTATION_WIN32) DWORD timeout = get_timeout(timeout_ms); @@ -329,7 +329,7 @@ bool IPCChannelEnd::recv(int timeout_ms) noexcept #endif return false; } while (size > IPC_CHANNEL_MSG_SIZE); - memcpy(recv_data, m_in->data, size); + memcpy(recv_data, m_in->data, size); //TODO: memcpy volatile save? } return true; } diff --git a/src/threading/ipc_channel.h b/src/threading/ipc_channel.h index 5b0a381e4..b26785618 100644 --- a/src/threading/ipc_channel.h +++ b/src/threading/ipc_channel.h @@ -168,7 +168,9 @@ public: // If send, recv, or exchange return false (=timeout), stop using the channel. <--- TODO:why? // Note: timeouts may be for receiving any response, not a whole message. - bool send(const void *data, size_t size, int timeout_ms = -1) noexcept + // Returns false on timeout + [[nodiscard]] + bool sendWithTimeout(const void *data, size_t size, int timeout_ms) noexcept { if (size <= IPC_CHANNEL_MSG_SIZE) { sendSmall(data, size); @@ -178,14 +180,40 @@ public: } } - bool recv(int timeout_ms = -1) noexcept; - - bool exchange(const void *data, size_t size, int timeout_ms = -1) noexcept + // Same as above + void send(const void *data, size_t size) noexcept { - return send(data, size, timeout_ms) && recv(timeout_ms); + (void)sendWithTimeout(data, size, -1); + } + + // Returns false on timeout. + // Otherwise returns true, and data is available via getRecvData(). + [[nodiscard]] + bool recvWithTimeout(int timeout_ms) noexcept; + + // Same as above + void recv() noexcept + { + (void)recvWithTimeout(-1); + } + + // Returns false on timeout + // Otherwise returns true, and data is available via getRecvData(). + [[nodiscard]] + bool exchangeWithTimeout(const void *data, size_t size, int timeout_ms) noexcept + { + return sendWithTimeout(data, size, timeout_ms) + && recvWithTimeout(timeout_ms); + } + + // Same as above + void exchange(const void *data, size_t size) noexcept + { + (void)exchangeWithTimeout(data, size, -1); } // Get the content of the last received message + // TODO: u8 *, or string_view? inline const void *getRecvData() const noexcept { return m_large_recv.data(); } inline size_t getRecvSize() const noexcept { return m_recv_size; } @@ -208,6 +236,7 @@ private: {} #endif + // TODO: u8 *, or string_view? void sendSmall(const void *data, size_t size) noexcept; // returns false on timeout diff --git a/src/unittest/test_threading.cpp b/src/unittest/test_threading.cpp index a8950d114..0918df732 100644 --- a/src/unittest/test_threading.cpp +++ b/src/unittest/test_threading.cpp @@ -282,25 +282,26 @@ void TestThreading::testIPCChannel() IPCChannelEnd end_b = IPCChannelEnd::makeB(std::move(resources_second)); for (;;) { - UASSERT(end_b.recv()); - UASSERT(end_b.send(end_b.getRecvData(), end_b.getRecvSize())); + UASSERT(end_b.recvWithTimeout(-1)); + UASSERT(end_b.sendWithTimeout(end_b.getRecvData(), end_b.getRecvSize(), -1)); if (end_b.getRecvSize() == 0) break; } }); char buf[20000] = {}; - for (int i = sizeof(buf); i > 0; i -= 1000) { + for (int i = sizeof(buf); i > 0; i -= 100) { buf[i - 1] = 123; - UASSERT(end_a.exchange(buf, i)); + UASSERT(end_a.exchangeWithTimeout(buf, i, -1)); UASSERTEQ(int, end_a.getRecvSize(), i); UASSERTEQ(int, ((const char *)end_a.getRecvData())[i - 1], 123); } - UASSERT(end_a.exchange(buf, 0)); + UASSERT(end_a.exchangeWithTimeout(buf, 0, -1)); UASSERTEQ(int, end_a.getRecvSize(), 0); thread_b.join(); - UASSERT(!end_a.exchange(buf, 0, 1000)); + // other side dead ==> should time out + UASSERT(!end_a.exchangeWithTimeout(buf, 0, 200)); }