mirror of
https://github.com/mutouyun/cpp-ipc.git
synced 2025-12-06 16:56:45 +08:00
for linux
This commit is contained in:
parent
bce3894707
commit
aaf67858c2
@ -50,20 +50,18 @@ int main() {
|
|||||||
}
|
}
|
||||||
std::cout << dat << std::endl;
|
std::cout << dat << std::endl;
|
||||||
}
|
}
|
||||||
|
std::cout << id << " receiver is quit..." << std::endl;
|
||||||
}};
|
}};
|
||||||
|
|
||||||
for (/*int i = 1*/;; /*++i*/) {
|
for (/*int i = 1*/;; /*++i*/) {
|
||||||
std::cin >> buf;
|
std::cin >> buf;
|
||||||
if (buf.empty()) break;
|
if (buf.empty() || (buf == quit__)) break;
|
||||||
// std::cout << "[" << i << "]" << std::endl;
|
// std::cout << "[" << i << "]" << std::endl;
|
||||||
sender__.send(id + "> " + buf);
|
sender__.send(id + "> " + buf);
|
||||||
if (buf == quit__) {
|
|
||||||
receiver__.disconnect();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
receiver__.disconnect();
|
||||||
r.join();
|
r.join();
|
||||||
std::cout << id << " is quit..." << std::endl;
|
std::cout << id << " sender is quit..." << std::endl;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -241,6 +241,11 @@ class waiter_helper {
|
|||||||
std::atomic<unsigned> waiting_ { 0 };
|
std::atomic<unsigned> waiting_ { 0 };
|
||||||
long counter_ = 0;
|
long counter_ = 0;
|
||||||
|
|
||||||
|
enum : unsigned {
|
||||||
|
destruct_mask = (std::numeric_limits<unsigned>::max)() >> 1,
|
||||||
|
destruct_flag = ~destruct_mask
|
||||||
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
using handle_t = std::tuple<ipc::string, sem_helper::handle_t, sem_helper::handle_t>;
|
using handle_t = std::tuple<ipc::string, sem_helper::handle_t, sem_helper::handle_t>;
|
||||||
|
|
||||||
@ -280,24 +285,33 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename F>
|
template <typename F>
|
||||||
bool wait_if(handle_t const & h, F&& pred, std::size_t tm = invalid_value) {
|
bool wait_if(handle_t const & h, std::atomic<bool> const & enabled, F&& pred, std::size_t tm = invalid_value) {
|
||||||
|
if (!enabled.load(std::memory_order_acquire)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
waiting_.fetch_add(1, std::memory_order_release);
|
waiting_.fetch_add(1, std::memory_order_release);
|
||||||
auto finally = ipc::guard([this] {
|
auto finally = ipc::guard([this] {
|
||||||
waiting_->fetch_sub(1, std::memory_order_release);
|
waiting_.fetch_sub(1, std::memory_order_release);
|
||||||
});
|
});
|
||||||
{
|
{
|
||||||
IPC_UNUSED_ auto guard = ipc::detail::unique_lock(lock_);
|
IPC_UNUSED_ auto guard = ipc::detail::unique_lock(lock_);
|
||||||
if (!std::forward<F>(pred)()) return true;
|
if (!std::forward<F>(pred)()) return true;
|
||||||
++ counter_;
|
++ counter_;
|
||||||
}
|
}
|
||||||
bool ret = sem_helper::wait(std::get<1>(h), tm);
|
bool ret = false;
|
||||||
|
do {
|
||||||
|
if (!enabled.load(std::memory_order_acquire)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
ret = sem_helper::wait(std::get<1>(h), tm);
|
||||||
|
} while (waiting_.load(std::memory_order_acquire) & destruct_flag);
|
||||||
finally.do_exit();
|
finally.do_exit();
|
||||||
ret = sem_helper::post(std::get<2>(h)) && ret;
|
ret = sem_helper::post(std::get<2>(h)) && ret;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool notify(handle_t const & h) {
|
bool notify(handle_t const & h) {
|
||||||
if (waiting_.load(std::memory_order_acquire) == 0) {
|
if ((waiting_.load(std::memory_order_acquire) & destruct_mask) == 0) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
bool ret = true;
|
bool ret = true;
|
||||||
@ -311,7 +325,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool broadcast(handle_t const & h) {
|
bool broadcast(handle_t const & h) {
|
||||||
if (waiting_.load(std::memory_order_acquire) == 0) {
|
if ((waiting_.load(std::memory_order_acquire) & destruct_mask) == 0) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
bool ret = true;
|
bool ret = true;
|
||||||
@ -327,6 +341,28 @@ public:
|
|||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool emit_destruction(handle_t const & h) {
|
||||||
|
if ((waiting_.load(std::memory_order_acquire) & destruct_mask) == 0) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
bool ret = true;
|
||||||
|
IPC_UNUSED_ auto guard = ipc::detail::unique_lock(lock_);
|
||||||
|
waiting_.fetch_or(destruct_flag, std::memory_order_relaxed);
|
||||||
|
IPC_UNUSED_ auto finally = ipc::guard([this] {
|
||||||
|
waiting_.fetch_and(destruct_mask, std::memory_order_relaxed);
|
||||||
|
});
|
||||||
|
if (counter_ > 0) {
|
||||||
|
for (long i = 0; i < counter_; ++i) {
|
||||||
|
ret = ret && sem_helper::post(std::get<1>(h));
|
||||||
|
}
|
||||||
|
do {
|
||||||
|
-- counter_;
|
||||||
|
ret = ret && sem_helper::wait(std::get<2>(h), default_timeout);
|
||||||
|
} while (counter_ > 0);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class waiter {
|
class waiter {
|
||||||
@ -360,19 +396,24 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename F>
|
template <typename F>
|
||||||
bool wait_if(handle_t h, F&& pred, std::size_t tm = invalid_value) {
|
bool wait_if(handle_t h, std::atomic<bool> const & enabled, F && pred, std::size_t tm = invalid_value) {
|
||||||
if (h == invalid()) return false;
|
if (h == invalid()) return false;
|
||||||
return helper_.wait_if(h, std::forward<F>(pred), tm);
|
return helper_.wait_if(h, enabled, std::forward<F>(pred), tm);
|
||||||
}
|
}
|
||||||
|
|
||||||
void notify(handle_t h) {
|
bool notify(handle_t h) {
|
||||||
if (h == invalid()) return;
|
if (h == invalid()) return false;
|
||||||
helper_.notify(h);
|
return helper_.notify(h);
|
||||||
}
|
}
|
||||||
|
|
||||||
void broadcast(handle_t h) {
|
bool broadcast(handle_t h) {
|
||||||
if (h == invalid()) return;
|
if (h == invalid()) return false;
|
||||||
helper_.broadcast(h);
|
return helper_.broadcast(h);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool emit_destruction(handle_t h) {
|
||||||
|
if (h == invalid()) return false;
|
||||||
|
return helper_.emit_destruction(h);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -241,7 +241,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename F>
|
template <typename F>
|
||||||
bool wait_if(F&& pred, std::size_t tm = invalid_value) {
|
bool wait_if(F && pred, std::size_t tm = invalid_value) {
|
||||||
if (!valid()) return false;
|
if (!valid()) return false;
|
||||||
return w_->wait_if(h_, enabled_, std::forward<F>(pred), tm);
|
return w_->wait_if(h_, enabled_, std::forward<F>(pred), tm);
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user