diff --git a/src/benchmark/benchmark_ipc_channel.cpp b/src/benchmark/benchmark_ipc_channel.cpp index 2340d8147..e81f55cf4 100644 --- a/src/benchmark/benchmark_ipc_channel.cpp +++ b/src/benchmark/benchmark_ipc_channel.cpp @@ -27,8 +27,8 @@ TEST_CASE("benchmark_ipc_channel") // echos back messages. stops if "" is sent for (;;) { end_b.recv(); - end_b.send(end_b.getRecvData()); - if (end_b.getRecvData().size() == 0) + end_b.send(end_b.getRecvData(), end_b.getRecvSize()); + if (end_b.getRecvSize() == 0) break; } }); @@ -39,8 +39,8 @@ TEST_CASE("benchmark_ipc_channel") BENCHMARK("simple_call_1", i) { char buf[16] = {}; buf[i & 0xf] = i; - end_a.exchange({buf, 16}); - return end_a.getRecvData()[i & 0xf]; + end_a.exchange(buf, 16); + return reinterpret_cast(end_a.getRecvData())[i & 0xf]; }; BENCHMARK("simple_call_1000", i) { @@ -48,14 +48,14 @@ TEST_CASE("benchmark_ipc_channel") buf[i & 0xf] = i; for (int k = 0; k < 1000; ++k) { buf[0] = k & 0xff; - end_a.exchange({buf, 16}); + end_a.exchange(buf, 16); } - return end_a.getRecvData()[i & 0xf]; + return reinterpret_cast(end_a.getRecvData())[i & 0xf]; }; // stop thread_b - end_a.exchange({nullptr, 0}); - REQUIRE(end_a.getRecvData().size() == 0); + end_a.exchange(nullptr, 0); + REQUIRE(end_a.getRecvSize() == 0); thread_b.join(); } diff --git a/src/threading/ipc_channel.cpp b/src/threading/ipc_channel.cpp index d053161c5..59b90c4f5 100644 --- a/src/threading/ipc_channel.cpp +++ b/src/threading/ipc_channel.cpp @@ -278,38 +278,35 @@ IPCChannelEnd IPCChannelEnd::makeB(std::unique_ptr resource #endif // !defined(IPC_CHANNEL_IMPLEMENTATION_WIN32) } -void IPCChannelEnd::sendSmall(std::string_view data) noexcept +void IPCChannelEnd::sendSmall(const void *data, size_t size) noexcept { - write_once(&m_dir.buf_out->size, data.size()); + write_once(&m_dir.buf_out->size, size); - if (data.size() != 0) - memcpy(m_dir.buf_out->data, data.data(), data.size()); + if (size != 0) + memcpy(m_dir.buf_out->data, data, size); post_out(&m_dir); } -bool IPCChannelEnd::sendLarge(std::string_view data, int timeout_ms) noexcept +bool IPCChannelEnd::sendLarge(const void *data, size_t size, int timeout_ms) noexcept { u64 timeout_ms_abs = timeout_ms < 0 ? 0 : porting::getTimeMs() + timeout_ms; - write_once(&m_dir.buf_out->size, data.size()); + write_once(&m_dir.buf_out->size, size); - size_t size = data.size(); - const u8 *ptr = reinterpret_cast(data.data()); - - while (size > IPC_CHANNEL_MSG_SIZE) { - memcpy(m_dir.buf_out->data, ptr, IPC_CHANNEL_MSG_SIZE); + do { + memcpy(m_dir.buf_out->data, data, IPC_CHANNEL_MSG_SIZE); post_out(&m_dir); if (!wait_in(&m_dir, timeout_ms_abs)) return false; size -= IPC_CHANNEL_MSG_SIZE; - ptr = ptr + IPC_CHANNEL_MSG_SIZE; - } + data = (u8 *)data + IPC_CHANNEL_MSG_SIZE; + } while (size > IPC_CHANNEL_MSG_SIZE); if (size != 0) - memcpy(m_dir.buf_out->data, ptr, size); + memcpy(m_dir.buf_out->data, data, size); post_out(&m_dir); return true; diff --git a/src/threading/ipc_channel.h b/src/threading/ipc_channel.h index 2d8e1a689..0cd8b4962 100644 --- a/src/threading/ipc_channel.h +++ b/src/threading/ipc_channel.h @@ -27,7 +27,6 @@ with this program; if not, write to the Free Software Foundation, Inc., #include #include #include -#include #if defined(_WIN32) #define IPC_CHANNEL_IMPLEMENTATION_WIN32 @@ -194,20 +193,20 @@ public: // Returns false on timeout [[nodiscard]] - bool sendWithTimeout(std::string_view data, int timeout_ms) noexcept + bool sendWithTimeout(const void *data, size_t size, int timeout_ms) noexcept { - if (data.size() <= IPC_CHANNEL_MSG_SIZE) { - sendSmall(data); + if (size <= IPC_CHANNEL_MSG_SIZE) { + sendSmall(data, size); return true; } else { - return sendLarge(data, timeout_ms); + return sendLarge(data, size, timeout_ms); } } // Same as above - void send(std::string_view data) noexcept + void send(const void *data, size_t size) noexcept { - (void)sendWithTimeout(data, -1); + (void)sendWithTimeout(data, size, -1); } // Returns false on timeout. @@ -224,31 +223,33 @@ public: // Returns false on timeout // Otherwise returns true, and data is available via getRecvData(). [[nodiscard]] - bool exchangeWithTimeout(std::string_view data, int timeout_ms) noexcept + bool exchangeWithTimeout(const void *data, size_t size, int timeout_ms) noexcept { - return sendWithTimeout(data, timeout_ms) + return sendWithTimeout(data, size, timeout_ms) && recvWithTimeout(timeout_ms); } // Same as above - void exchange(std::string_view data) noexcept + void exchange(const void *data, size_t size) noexcept { - (void)exchangeWithTimeout(data, -1); + (void)exchangeWithTimeout(data, size, -1); } // Get the content of the last received message - std::string_view getRecvData() const noexcept - { return {reinterpret_cast(m_large_recv.data()), m_recv_size}; } + // TODO: u8 *, or string_view? + const void *getRecvData() const noexcept { return m_large_recv.data(); } + size_t getRecvSize() const noexcept { return m_recv_size; } private: IPCChannelEnd(std::unique_ptr resources, Dir dir) : m_resources(std::move(resources)), m_dir(dir) {} - void sendSmall(std::string_view data) noexcept; + // TODO: u8 *, or string_view? + void sendSmall(const void *data, size_t size) noexcept; // returns false on timeout - bool sendLarge(std::string_view data, int timeout_ms) noexcept; + bool sendLarge(const void *data, size_t size, int timeout_ms) noexcept; std::unique_ptr m_resources; Dir m_dir; diff --git a/src/unittest/test_threading.cpp b/src/unittest/test_threading.cpp index a2e1298bb..7db619b04 100644 --- a/src/unittest/test_threading.cpp +++ b/src/unittest/test_threading.cpp @@ -237,8 +237,8 @@ void TestThreading::testIPCChannel() // echos back messages. stops if "" is sent for (;;) { UASSERT(end_b.recvWithTimeout(-1)); - UASSERT(end_b.sendWithTimeout(end_b.getRecvData(), -1)); - if (end_b.getRecvData().size() == 0) + UASSERT(end_b.sendWithTimeout(end_b.getRecvData(), end_b.getRecvSize(), -1)); + if (end_b.getRecvSize() == 0) break; } }); @@ -246,17 +246,17 @@ void TestThreading::testIPCChannel() char buf[20000] = {}; for (int i = sizeof(buf); i > 0; i -= 100) { buf[i - 1] = 123; - UASSERT(end_a.exchangeWithTimeout({buf, (size_t)i}, -1)); - UASSERTEQ(int, end_a.getRecvData().size(), i); - UASSERTEQ(int, end_a.getRecvData().data()[i - 1], 123); + UASSERT(end_a.exchangeWithTimeout(buf, i, -1)); + UASSERTEQ(int, end_a.getRecvSize(), i); + UASSERTEQ(int, ((const char *)end_a.getRecvData())[i - 1], 123); } // stop thread_b - UASSERT(end_a.exchangeWithTimeout({buf, 0}, -1)); - UASSERTEQ(int, end_a.getRecvData().size(), 0); + UASSERT(end_a.exchangeWithTimeout(buf, 0, -1)); + UASSERTEQ(int, end_a.getRecvSize(), 0); thread_b.join(); // other side dead ==> should time out - UASSERT(!end_a.exchangeWithTimeout({buf, 0}, 200)); + UASSERT(!end_a.exchangeWithTimeout(buf, 0, 200)); }