mirror of
https://github.com/mutouyun/cpp-ipc.git
synced 2025-12-07 01:06:45 +08:00
rw_lock (TBD)
This commit is contained in:
parent
f3a73fcc4d
commit
0a17257388
@ -27,7 +27,13 @@ public:
|
|||||||
void swap(channel& rhs);
|
void swap(channel& rhs);
|
||||||
channel& operator=(channel rhs);
|
channel& operator=(channel rhs);
|
||||||
|
|
||||||
|
bool valid(void) const;
|
||||||
|
char const * name (void) const;
|
||||||
|
|
||||||
|
channel clone(void) const;
|
||||||
|
|
||||||
bool connect(char const * name);
|
bool connect(char const * name);
|
||||||
|
void disconnect(void);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
class channel_;
|
class channel_;
|
||||||
|
|||||||
66
src/ipc.cpp
66
src/ipc.cpp
@ -1,7 +1,10 @@
|
|||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
#include <atomic>
|
||||||
|
#include <thread>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
#include <string>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <utility>
|
#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__;
|
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) {
|
queue_t* queue_of(handle_t h) {
|
||||||
if (h == nullptr) {
|
if (h == nullptr) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
@ -138,7 +177,8 @@ std::vector<byte_t> recv(handle_t h) {
|
|||||||
|
|
||||||
class channel::channel_ {
|
class channel::channel_ {
|
||||||
public:
|
public:
|
||||||
handle_t h_;
|
handle_t h_ = nullptr;
|
||||||
|
std::string n_;
|
||||||
};
|
};
|
||||||
|
|
||||||
channel::channel(void)
|
channel::channel(void)
|
||||||
@ -147,7 +187,7 @@ channel::channel(void)
|
|||||||
|
|
||||||
channel::channel(char const * name)
|
channel::channel(char const * name)
|
||||||
: channel() {
|
: channel() {
|
||||||
connect(name);
|
this->connect(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
channel::channel(channel&& rhs)
|
channel::channel(channel&& rhs)
|
||||||
@ -168,8 +208,28 @@ channel& channel::operator=(channel rhs) {
|
|||||||
return *this;
|
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) {
|
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
|
} // namespace ipc
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user