mirror of
https://github.com/luanti-org/luanti.git
synced 2025-08-11 17:51:04 +00:00
deduplicate test helper
This commit is contained in:
parent
37358bd8fe
commit
2af85d05fa
4 changed files with 68 additions and 93 deletions
|
@ -23,53 +23,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
|
||||||
TEST_CASE("benchmark_ipc_channel")
|
TEST_CASE("benchmark_ipc_channel")
|
||||||
{
|
{
|
||||||
// same as in test_threading.cpp (TODO: remove duplication)
|
auto end_a_thread_b_p = make_test_ipc_channel([](IPCChannelEnd end_b) {
|
||||||
struct IPCChannelResourcesSingleProcess final : public IPCChannelResources
|
// echos back messages. stops if "" is sent
|
||||||
{
|
|
||||||
void cleanupLast() noexcept override
|
|
||||||
{
|
|
||||||
delete data.shared;
|
|
||||||
#ifdef IPC_CHANNEL_IMPLEMENTATION_WIN32
|
|
||||||
CloseHandle(data.sem_b);
|
|
||||||
CloseHandle(data.sem_a);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void cleanupNotLast() noexcept override
|
|
||||||
{
|
|
||||||
// nothing to do (i.e. no unmapping needed)
|
|
||||||
}
|
|
||||||
|
|
||||||
~IPCChannelResourcesSingleProcess() override { cleanup(); }
|
|
||||||
};
|
|
||||||
|
|
||||||
auto resource_data = [] {
|
|
||||||
auto shared = new IPCChannelShared();
|
|
||||||
|
|
||||||
#ifdef IPC_CHANNEL_IMPLEMENTATION_WIN32
|
|
||||||
HANDLE sem_a = CreateSemaphoreA(nullptr, 0, 1, nullptr);
|
|
||||||
REQUIRE(sem_a != INVALID_HANDLE_VALUE);
|
|
||||||
|
|
||||||
HANDLE sem_b = CreateSemaphoreA(nullptr, 0, 1, nullptr);
|
|
||||||
REQUIRE(sem_b != INVALID_HANDLE_VALUE);
|
|
||||||
|
|
||||||
return IPCChannelResources::Data{shared, sem_a, sem_b};
|
|
||||||
#else
|
|
||||||
return IPCChannelResources::Data{shared};
|
|
||||||
#endif
|
|
||||||
}();
|
|
||||||
|
|
||||||
auto resources_first = std::make_unique<IPCChannelResourcesSingleProcess>();
|
|
||||||
resources_first->setFirst(resource_data);
|
|
||||||
|
|
||||||
IPCChannelEnd end_a = IPCChannelEnd::makeA(std::move(resources_first));
|
|
||||||
|
|
||||||
// echos back messages. stops if "" is sent
|
|
||||||
std::thread thread_b([=] {
|
|
||||||
auto resources_second = std::make_unique<IPCChannelResourcesSingleProcess>();
|
|
||||||
resources_second->setSecond(resource_data);
|
|
||||||
IPCChannelEnd end_b = IPCChannelEnd::makeB(std::move(resources_second));
|
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
end_b.recv();
|
end_b.recv();
|
||||||
end_b.send(end_b.getRecvData(), end_b.getRecvSize());
|
end_b.send(end_b.getRecvData(), end_b.getRecvSize());
|
||||||
|
@ -77,6 +32,9 @@ TEST_CASE("benchmark_ipc_channel")
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
// Can't use structured bindings before C++20, because of lamda captures below.
|
||||||
|
auto end_a = std::move(end_a_thread_b_p.first);
|
||||||
|
auto thread_b = std::move(end_a_thread_b_p.second);
|
||||||
|
|
||||||
BENCHMARK("simple_call_1", i) {
|
BENCHMARK("simple_call_1", i) {
|
||||||
char buf[16] = {};
|
char buf[16] = {};
|
||||||
|
|
|
@ -353,3 +353,36 @@ bool IPCChannelEnd::recvWithTimeout(int timeout_ms) noexcept
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::pair<IPCChannelEnd, std::thread> make_test_ipc_channel(
|
||||||
|
const std::function<void(IPCChannelEnd)> &fun)
|
||||||
|
{
|
||||||
|
auto resource_data = [] {
|
||||||
|
auto shared = new IPCChannelShared();
|
||||||
|
|
||||||
|
#ifdef IPC_CHANNEL_IMPLEMENTATION_WIN32
|
||||||
|
HANDLE sem_a = CreateSemaphoreA(nullptr, 0, 1, nullptr);
|
||||||
|
HANDLE sem_b = CreateSemaphoreA(nullptr, 0, 1, nullptr);
|
||||||
|
FATAL_ERROR_IF(!sem_a || !sem_b, "CreateSemaphoreA failed");
|
||||||
|
|
||||||
|
return IPCChannelResources::Data{shared, sem_a, sem_b};
|
||||||
|
#else
|
||||||
|
return IPCChannelResources::Data{shared};
|
||||||
|
#endif
|
||||||
|
}();
|
||||||
|
|
||||||
|
auto resources_first = std::make_unique<IPCChannelResourcesSingleProcess>();
|
||||||
|
resources_first->setFirst(resource_data);
|
||||||
|
|
||||||
|
IPCChannelEnd end_a = IPCChannelEnd::makeA(std::move(resources_first));
|
||||||
|
|
||||||
|
std::thread thread_b([=] {
|
||||||
|
auto resources_second = std::make_unique<IPCChannelResourcesSingleProcess>();
|
||||||
|
resources_second->setSecond(resource_data);
|
||||||
|
IPCChannelEnd end_b = IPCChannelEnd::makeB(std::move(resources_second));
|
||||||
|
|
||||||
|
fun(std::move(end_b));
|
||||||
|
});
|
||||||
|
|
||||||
|
return {std::move(end_a), std::move(thread_b)};
|
||||||
|
}
|
||||||
|
|
|
@ -25,6 +25,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
|
#include <thread>
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
#define IPC_CHANNEL_IMPLEMENTATION_WIN32
|
#define IPC_CHANNEL_IMPLEMENTATION_WIN32
|
||||||
|
@ -256,3 +258,29 @@ private:
|
||||||
// (this buffer only grows)
|
// (this buffer only grows)
|
||||||
std::vector<u8> m_large_recv = std::vector<u8>(IPC_CHANNEL_MSG_SIZE);
|
std::vector<u8> m_large_recv = std::vector<u8>(IPC_CHANNEL_MSG_SIZE);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// For testing purposes
|
||||||
|
struct IPCChannelResourcesSingleProcess final : public IPCChannelResources
|
||||||
|
{
|
||||||
|
void cleanupLast() noexcept override
|
||||||
|
{
|
||||||
|
delete data.shared;
|
||||||
|
#ifdef IPC_CHANNEL_IMPLEMENTATION_WIN32
|
||||||
|
CloseHandle(data.sem_b);
|
||||||
|
CloseHandle(data.sem_a);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void cleanupNotLast() noexcept override
|
||||||
|
{
|
||||||
|
// nothing to do (i.e. no unmapping needed)
|
||||||
|
}
|
||||||
|
|
||||||
|
~IPCChannelResourcesSingleProcess() override { cleanup(); }
|
||||||
|
};
|
||||||
|
|
||||||
|
// For testing
|
||||||
|
// Returns one end and a thread holding the other end. The thread will execute
|
||||||
|
// fun, and pass it the other end.
|
||||||
|
std::pair<IPCChannelEnd, std::thread> make_test_ipc_channel(
|
||||||
|
const std::function<void(IPCChannelEnd)> &fun);
|
||||||
|
|
|
@ -236,52 +236,8 @@ void TestThreading::testTLS()
|
||||||
|
|
||||||
void TestThreading::testIPCChannel()
|
void TestThreading::testIPCChannel()
|
||||||
{
|
{
|
||||||
struct IPCChannelResourcesSingleProcess final : public IPCChannelResources
|
auto [end_a, thread_b] = make_test_ipc_channel([](IPCChannelEnd end_b) {
|
||||||
{
|
// echos back messages. stops if "" is sent
|
||||||
void cleanupLast() noexcept override
|
|
||||||
{
|
|
||||||
delete data.shared;
|
|
||||||
#ifdef IPC_CHANNEL_IMPLEMENTATION_WIN32
|
|
||||||
CloseHandle(data.sem_b);
|
|
||||||
CloseHandle(data.sem_a);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void cleanupNotLast() noexcept override
|
|
||||||
{
|
|
||||||
// nothing to do (i.e. no unmapping needed)
|
|
||||||
}
|
|
||||||
|
|
||||||
~IPCChannelResourcesSingleProcess() override { cleanup(); }
|
|
||||||
};
|
|
||||||
|
|
||||||
auto resource_data = [] {
|
|
||||||
auto shared = new IPCChannelShared();
|
|
||||||
|
|
||||||
#ifdef IPC_CHANNEL_IMPLEMENTATION_WIN32
|
|
||||||
HANDLE sem_a = CreateSemaphoreA(nullptr, 0, 1, nullptr);
|
|
||||||
UASSERT(sem_a != INVALID_HANDLE_VALUE);
|
|
||||||
|
|
||||||
HANDLE sem_b = CreateSemaphoreA(nullptr, 0, 1, nullptr);
|
|
||||||
UASSERT(sem_b != INVALID_HANDLE_VALUE);
|
|
||||||
|
|
||||||
return IPCChannelResources::Data{shared, sem_a, sem_b};
|
|
||||||
#else
|
|
||||||
return IPCChannelResources::Data{shared};
|
|
||||||
#endif
|
|
||||||
}();
|
|
||||||
|
|
||||||
auto resources_first = std::make_unique<IPCChannelResourcesSingleProcess>();
|
|
||||||
resources_first->setFirst(resource_data);
|
|
||||||
|
|
||||||
IPCChannelEnd end_a = IPCChannelEnd::makeA(std::move(resources_first));
|
|
||||||
|
|
||||||
// echos back messages. stops if "" is sent
|
|
||||||
std::thread thread_b([=] {
|
|
||||||
auto resources_second = std::make_unique<IPCChannelResourcesSingleProcess>();
|
|
||||||
resources_second->setSecond(resource_data);
|
|
||||||
IPCChannelEnd end_b = IPCChannelEnd::makeB(std::move(resources_second));
|
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
UASSERT(end_b.recvWithTimeout(-1));
|
UASSERT(end_b.recvWithTimeout(-1));
|
||||||
UASSERT(end_b.sendWithTimeout(end_b.getRecvData(), end_b.getRecvSize(), -1));
|
UASSERT(end_b.sendWithTimeout(end_b.getRecvData(), end_b.getRecvSize(), -1));
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue