From a457a8975f14005833b6429bae9d5eea5182a744 Mon Sep 17 00:00:00 2001 From: mutouyun Date: Tue, 21 Sep 2021 13:09:59 +0800 Subject: [PATCH] using 'signal' to quit waiting explicitly --- demo/msg_que/main.cpp | 4 ++-- demo/send_recv/main.cpp | 30 ++++++++++++++++++++++++++++-- src/libipc/ipc.cpp | 14 ++++++-------- test/test_sync.cpp | 5 ++++- 4 files changed, 40 insertions(+), 13 deletions(-) diff --git a/demo/msg_que/main.cpp b/demo/msg_que/main.cpp index 27c5ce6..eda7f51 100644 --- a/demo/msg_que/main.cpp +++ b/demo/msg_que/main.cpp @@ -20,8 +20,8 @@ constexpr char const mode_r__[] = "r"; constexpr std::size_t const min_sz = 128; constexpr std::size_t const max_sz = 1024 * 16; -std::atomic is_quit__{ false }; -std::atomic size_counter__{ 0 }; +std::atomic is_quit__ {false}; +std::atomic size_counter__ {0}; using msg_que_t = ipc::chan; diff --git a/demo/send_recv/main.cpp b/demo/send_recv/main.cpp index 3acc52a..52287c2 100644 --- a/demo/send_recv/main.cpp +++ b/demo/send_recv/main.cpp @@ -1,17 +1,24 @@ +#include + #include #include #include #include +#include #include "libipc/ipc.h" namespace { +std::atomic is_quit__ {false}; +ipc::channel *ipc__ = nullptr; + void do_send(int size, int interval) { ipc::channel ipc {"ipc", ipc::sender}; + ipc__ = &ipc; std::string buffer(size, 'A'); - while (true) { + while (!is_quit__.load(std::memory_order_acquire)) { std::cout << "send size: " << buffer.size() + 1 << "\n"; ipc.send(buffer, 0/*tm*/); std::this_thread::sleep_for(std::chrono::milliseconds(interval)); @@ -20,11 +27,13 @@ void do_send(int size, int interval) { void do_recv(int interval) { ipc::channel ipc {"ipc", ipc::receiver}; - while (true) { + ipc__ = &ipc; + while (!is_quit__.load(std::memory_order_acquire)) { ipc::buff_t recv; for (int k = 1; recv.empty(); ++k) { std::cout << "recv waiting... " << k << "\n"; recv = ipc.recv(interval); + if (is_quit__.load(std::memory_order_acquire)) return; } std::cout << "recv size: " << recv.size() << "\n"; } @@ -34,6 +43,23 @@ void do_recv(int interval) { int main(int argc, char ** argv) { if (argc < 3) return -1; + + auto exit = [](int) { + is_quit__.store(true, std::memory_order_release); + if (ipc__ != nullptr) ipc__->disconnect(); + }; + ::signal(SIGINT , exit); + ::signal(SIGABRT , exit); + ::signal(SIGSEGV , exit); + ::signal(SIGTERM , exit); +#if defined(WIN64) || defined(_WIN64) || defined(__WIN64__) || \ + defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__) || \ + defined(WINCE) || defined(_WIN32_WCE) + ::signal(SIGBREAK, exit); +#else + ::signal(SIGHUP , exit); +#endif + std::string mode {argv[1]}; if (mode == "send") { if (argc < 4) return -1; diff --git a/src/libipc/ipc.cpp b/src/libipc/ipc.cpp index d23c556..2713de3 100755 --- a/src/libipc/ipc.cpp +++ b/src/libipc/ipc.cpp @@ -301,15 +301,13 @@ template bool wait_for(W& waiter, F&& pred, std::uint64_t tm) { if (tm == 0) return !pred(); for (unsigned k = 0; pred();) { - bool loop = true, ret = true; - ipc::sleep(k, [&k, &loop, &ret, &waiter, &pred, tm] { - ret = waiter.wait_if([&loop, &pred] { - return loop = pred(); - }, tm); - k = 0; + bool ret = true; + ipc::sleep(k, [&k, &ret, &waiter, &pred, tm] { + ret = waiter.wait_if(std::forward(pred), tm); + k = 0; }); - if (!ret ) return false; // timeout or fail - if (!loop) break; + if (!ret) return false; // timeout or fail + if (k == 0) break; // k has been reset } return true; } diff --git a/test/test_sync.cpp b/test/test_sync.cpp index d966e30..84ace7b 100644 --- a/test/test_sync.cpp +++ b/test/test_sync.cpp @@ -162,6 +162,9 @@ TEST(Sync, Condition) { for (auto &t : test_conds) t.join(); } +/** + * https://stackoverflow.com/questions/51730660/is-this-a-bug-in-glibc-pthread +*/ TEST(Sync, ConditionRobust) { printf("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 1\n"); ipc::sync::condition cond {"test-cond"}; @@ -180,7 +183,7 @@ TEST(Sync, ConditionRobust) { } std::this_thread::sleep_for(std::chrono::seconds(1)); printf("WWWWWWWWWWWWWWWWWWWWWWWWWWWWWW 4\n"); - cond.notify(); + cond.broadcast(); printf("WWWWWWWWWWWWWWWWWWWWWWWWWWWWWW 5\n"); }}; printf("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 4\n");