mirror of
https://github.com/mutouyun/cpp-ipc.git
synced 2025-12-06 16:56:45 +08:00
rw_lock (TBD)
This commit is contained in:
parent
f3a73fcc4d
commit
0a17257388
@ -27,7 +27,13 @@ public:
|
||||
void swap(channel& rhs);
|
||||
channel& operator=(channel rhs);
|
||||
|
||||
bool valid(void) const;
|
||||
char const * name (void) const;
|
||||
|
||||
channel clone(void) const;
|
||||
|
||||
bool connect(char const * name);
|
||||
void disconnect(void);
|
||||
|
||||
private:
|
||||
class channel_;
|
||||
|
||||
66
src/ipc.cpp
66
src/ipc.cpp
@ -1,7 +1,10 @@
|
||||
#include <unordered_map>
|
||||
#include <atomic>
|
||||
#include <thread>
|
||||
#include <memory>
|
||||
#include <type_traits>
|
||||
#include <cstring>
|
||||
#include <string>
|
||||
#include <algorithm>
|
||||
#include <utility>
|
||||
|
||||
@ -25,6 +28,42 @@ using guard_t = std::unique_ptr<std::remove_pointer_t<handle_t>, void(*)(handle_
|
||||
|
||||
std::unordered_map<handle_t, queue_t> h2q__;
|
||||
|
||||
class rw_lock {
|
||||
std::atomic_size_t lc_ { 0 };
|
||||
|
||||
enum : std::size_t {
|
||||
w_flag = std::numeric_limits<std::size_t>::max()
|
||||
};
|
||||
|
||||
public:
|
||||
void r_lock(void) {
|
||||
do {
|
||||
std::size_t old = lc_.load(std::memory_order_acquire);
|
||||
std::size_t unlocked = old + 1;
|
||||
if (unlocked &&
|
||||
lc_.compare_exchange_weak(old, unlocked, std::memory_order_acq_rel)) {
|
||||
break;
|
||||
}
|
||||
std::this_thread::yield();
|
||||
} while(1);
|
||||
}
|
||||
|
||||
void r_unlock(void) {
|
||||
lc_.fetch_sub(1, std::memory_order_release);
|
||||
}
|
||||
|
||||
void w_lock(void) {
|
||||
std::size_t expected = 0;
|
||||
while (!lc_.compare_exchange_weak(expected, w_flag, std::memory_order_acq_rel)) {
|
||||
std::this_thread::yield();
|
||||
}
|
||||
}
|
||||
|
||||
void w_unlock(void) {
|
||||
lc_.store(0, std::memory_order_release);
|
||||
}
|
||||
} h2q_lc__;
|
||||
|
||||
queue_t* queue_of(handle_t h) {
|
||||
if (h == nullptr) {
|
||||
return nullptr;
|
||||
@ -138,7 +177,8 @@ std::vector<byte_t> recv(handle_t h) {
|
||||
|
||||
class channel::channel_ {
|
||||
public:
|
||||
handle_t h_;
|
||||
handle_t h_ = nullptr;
|
||||
std::string n_;
|
||||
};
|
||||
|
||||
channel::channel(void)
|
||||
@ -147,7 +187,7 @@ channel::channel(void)
|
||||
|
||||
channel::channel(char const * name)
|
||||
: channel() {
|
||||
connect(name);
|
||||
this->connect(name);
|
||||
}
|
||||
|
||||
channel::channel(channel&& rhs)
|
||||
@ -168,8 +208,28 @@ channel& channel::operator=(channel rhs) {
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool channel::valid(void) const {
|
||||
return (p_ != nullptr) && (p_->h_ != nullptr);
|
||||
}
|
||||
|
||||
char const * channel::name(void) const {
|
||||
return (p_ == nullptr) ? "" : p_->n_.c_str();
|
||||
}
|
||||
|
||||
channel channel::clone(void) const {
|
||||
return { name() };
|
||||
}
|
||||
|
||||
bool channel::connect(char const * name) {
|
||||
return false;
|
||||
if (p_ == nullptr) return false;
|
||||
this->disconnect();
|
||||
p_->h_ = ipc::connect((p_->n_ = name).c_str());
|
||||
return valid();
|
||||
}
|
||||
|
||||
void channel::disconnect(void) {
|
||||
if (!valid()) return;
|
||||
ipc::disconnect(p_->h_);
|
||||
}
|
||||
|
||||
} // namespace ipc
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user