Skip to content

Commit a457a89

Browse files
committed
using 'signal' to quit waiting explicitly
1 parent f6bd578 commit a457a89

File tree

4 files changed

+40
-13
lines changed

4 files changed

+40
-13
lines changed

demo/msg_que/main.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@ constexpr char const mode_r__[] = "r";
2020
constexpr std::size_t const min_sz = 128;
2121
constexpr std::size_t const max_sz = 1024 * 16;
2222

23-
std::atomic<bool> is_quit__{ false };
24-
std::atomic<std::size_t> size_counter__{ 0 };
23+
std::atomic<bool> is_quit__ {false};
24+
std::atomic<std::size_t> size_counter__ {0};
2525

2626
using msg_que_t = ipc::chan<ipc::relat::single, ipc::relat::multi, ipc::trans::broadcast>;
2727

demo/send_recv/main.cpp

+28-2
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,24 @@
11

2+
#include <signal.h>
3+
24
#include <iostream>
35
#include <string>
46
#include <thread>
57
#include <chrono>
8+
#include <atomic>
69

710
#include "libipc/ipc.h"
811

912
namespace {
1013

14+
std::atomic<bool> is_quit__ {false};
15+
ipc::channel *ipc__ = nullptr;
16+
1117
void do_send(int size, int interval) {
1218
ipc::channel ipc {"ipc", ipc::sender};
19+
ipc__ = &ipc;
1320
std::string buffer(size, 'A');
14-
while (true) {
21+
while (!is_quit__.load(std::memory_order_acquire)) {
1522
std::cout << "send size: " << buffer.size() + 1 << "\n";
1623
ipc.send(buffer, 0/*tm*/);
1724
std::this_thread::sleep_for(std::chrono::milliseconds(interval));
@@ -20,11 +27,13 @@ void do_send(int size, int interval) {
2027

2128
void do_recv(int interval) {
2229
ipc::channel ipc {"ipc", ipc::receiver};
23-
while (true) {
30+
ipc__ = &ipc;
31+
while (!is_quit__.load(std::memory_order_acquire)) {
2432
ipc::buff_t recv;
2533
for (int k = 1; recv.empty(); ++k) {
2634
std::cout << "recv waiting... " << k << "\n";
2735
recv = ipc.recv(interval);
36+
if (is_quit__.load(std::memory_order_acquire)) return;
2837
}
2938
std::cout << "recv size: " << recv.size() << "\n";
3039
}
@@ -34,6 +43,23 @@ void do_recv(int interval) {
3443

3544
int main(int argc, char ** argv) {
3645
if (argc < 3) return -1;
46+
47+
auto exit = [](int) {
48+
is_quit__.store(true, std::memory_order_release);
49+
if (ipc__ != nullptr) ipc__->disconnect();
50+
};
51+
::signal(SIGINT , exit);
52+
::signal(SIGABRT , exit);
53+
::signal(SIGSEGV , exit);
54+
::signal(SIGTERM , exit);
55+
#if defined(WIN64) || defined(_WIN64) || defined(__WIN64__) || \
56+
defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__) || \
57+
defined(WINCE) || defined(_WIN32_WCE)
58+
::signal(SIGBREAK, exit);
59+
#else
60+
::signal(SIGHUP , exit);
61+
#endif
62+
3763
std::string mode {argv[1]};
3864
if (mode == "send") {
3965
if (argc < 4) return -1;

src/libipc/ipc.cpp

+6-8
Original file line numberDiff line numberDiff line change
@@ -301,15 +301,13 @@ template <typename W, typename F>
301301
bool wait_for(W& waiter, F&& pred, std::uint64_t tm) {
302302
if (tm == 0) return !pred();
303303
for (unsigned k = 0; pred();) {
304-
bool loop = true, ret = true;
305-
ipc::sleep(k, [&k, &loop, &ret, &waiter, &pred, tm] {
306-
ret = waiter.wait_if([&loop, &pred] {
307-
return loop = pred();
308-
}, tm);
309-
k = 0;
304+
bool ret = true;
305+
ipc::sleep(k, [&k, &ret, &waiter, &pred, tm] {
306+
ret = waiter.wait_if(std::forward<F>(pred), tm);
307+
k = 0;
310308
});
311-
if (!ret ) return false; // timeout or fail
312-
if (!loop) break;
309+
if (!ret) return false; // timeout or fail
310+
if (k == 0) break; // k has been reset
313311
}
314312
return true;
315313
}

test/test_sync.cpp

+4-1
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,9 @@ TEST(Sync, Condition) {
162162
for (auto &t : test_conds) t.join();
163163
}
164164

165+
/**
166+
* https://stackoverflow.com/questions/51730660/is-this-a-bug-in-glibc-pthread
167+
*/
165168
TEST(Sync, ConditionRobust) {
166169
printf("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 1\n");
167170
ipc::sync::condition cond {"test-cond"};
@@ -180,7 +183,7 @@ TEST(Sync, ConditionRobust) {
180183
}
181184
std::this_thread::sleep_for(std::chrono::seconds(1));
182185
printf("WWWWWWWWWWWWWWWWWWWWWWWWWWWWWW 4\n");
183-
cond.notify();
186+
cond.broadcast();
184187
printf("WWWWWWWWWWWWWWWWWWWWWWWWWWWWWW 5\n");
185188
}};
186189
printf("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 4\n");

0 commit comments

Comments
 (0)