mirror of
https://github.com/mutouyun/cpp-ipc.git
synced 2025-12-06 16:56:45 +08:00
修正全局变量初始化时序问题导致的内存访问异常
This commit is contained in:
parent
768e58f605
commit
9ac32df68d
@ -19,6 +19,8 @@ enum : unsigned {
|
|||||||
|
|
||||||
template <typename Flag>
|
template <typename Flag>
|
||||||
struct IPC_EXPORT chan_impl {
|
struct IPC_EXPORT chan_impl {
|
||||||
|
static ipc::handle_t inited();
|
||||||
|
|
||||||
static bool connect (ipc::handle_t * ph, char const * name, unsigned mode);
|
static bool connect (ipc::handle_t * ph, char const * name, unsigned mode);
|
||||||
static bool reconnect (ipc::handle_t * ph, unsigned mode);
|
static bool reconnect (ipc::handle_t * ph, unsigned mode);
|
||||||
static void disconnect(ipc::handle_t h);
|
static void disconnect(ipc::handle_t h);
|
||||||
@ -41,7 +43,7 @@ class chan_wrapper {
|
|||||||
private:
|
private:
|
||||||
using detail_t = chan_impl<Flag>;
|
using detail_t = chan_impl<Flag>;
|
||||||
|
|
||||||
ipc::handle_t h_ = nullptr;
|
ipc::handle_t h_ = detail_t::inited();
|
||||||
unsigned mode_ = ipc::sender;
|
unsigned mode_ = ipc::sender;
|
||||||
bool connected_ = false;
|
bool connected_ = false;
|
||||||
|
|
||||||
|
|||||||
@ -630,6 +630,12 @@ using policy_t = ipc::policy::choose<ipc::circ::elem_array, Flag>;
|
|||||||
|
|
||||||
namespace ipc {
|
namespace ipc {
|
||||||
|
|
||||||
|
template <typename Flag>
|
||||||
|
ipc::handle_t chan_impl<Flag>::inited() {
|
||||||
|
ipc::detail::waiter::init();
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
template <typename Flag>
|
template <typename Flag>
|
||||||
bool chan_impl<Flag>::connect(ipc::handle_t * ph, char const * name, unsigned mode) {
|
bool chan_impl<Flag>::connect(ipc::handle_t * ph, char const * name, unsigned mode) {
|
||||||
return detail_impl<policy_t<Flag>>::connect(ph, name, mode & receiver);
|
return detail_impl<policy_t<Flag>>::connect(ph, name, mode & receiver);
|
||||||
|
|||||||
@ -125,8 +125,8 @@ class mutex {
|
|||||||
IPC_UNUSED_ std::lock_guard<std::mutex> guard {info.lock};
|
IPC_UNUSED_ std::lock_guard<std::mutex> guard {info.lock};
|
||||||
auto it = info.mutex_handles.find(name);
|
auto it = info.mutex_handles.find(name);
|
||||||
if (it == info.mutex_handles.end()) {
|
if (it == info.mutex_handles.end()) {
|
||||||
it = curr_prog::get().mutex_handles.emplace(name,
|
it = info.mutex_handles.emplace(name,
|
||||||
curr_prog::shm_data::init{name}).first;
|
curr_prog::shm_data::init{name}).first;
|
||||||
}
|
}
|
||||||
mutex_ = &it->second.mtx;
|
mutex_ = &it->second.mtx;
|
||||||
ref_ = &it->second.ref;
|
ref_ = &it->second.ref;
|
||||||
@ -135,13 +135,14 @@ class mutex {
|
|||||||
template <typename F>
|
template <typename F>
|
||||||
void release_mutex(ipc::string const &name, F &&clear) {
|
void release_mutex(ipc::string const &name, F &&clear) {
|
||||||
if (name.empty()) return;
|
if (name.empty()) return;
|
||||||
IPC_UNUSED_ std::lock_guard<std::mutex> guard {curr_prog::get().lock};
|
auto &info = curr_prog::get();
|
||||||
auto it = curr_prog::get().mutex_handles.find(name);
|
IPC_UNUSED_ std::lock_guard<std::mutex> guard {info.lock};
|
||||||
if (it == curr_prog::get().mutex_handles.end()) {
|
auto it = info.mutex_handles.find(name);
|
||||||
|
if (it == info.mutex_handles.end()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (clear()) {
|
if (clear()) {
|
||||||
curr_prog::get().mutex_handles.erase(it);
|
info.mutex_handles.erase(it);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -149,6 +150,11 @@ public:
|
|||||||
mutex() = default;
|
mutex() = default;
|
||||||
~mutex() = default;
|
~mutex() = default;
|
||||||
|
|
||||||
|
static void init() {
|
||||||
|
// Avoid exception problems caused by static member initialization order.
|
||||||
|
curr_prog::get();
|
||||||
|
}
|
||||||
|
|
||||||
a0_mtx_t const *native() const noexcept {
|
a0_mtx_t const *native() const noexcept {
|
||||||
return valid() ? mutex_->native() : nullptr;
|
return valid() ? mutex_->native() : nullptr;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -55,8 +55,8 @@ class mutex {
|
|||||||
IPC_UNUSED_ std::lock_guard<std::mutex> guard {info.lock};
|
IPC_UNUSED_ std::lock_guard<std::mutex> guard {info.lock};
|
||||||
auto it = info.mutex_handles.find(name);
|
auto it = info.mutex_handles.find(name);
|
||||||
if (it == info.mutex_handles.end()) {
|
if (it == info.mutex_handles.end()) {
|
||||||
it = curr_prog::get().mutex_handles.emplace(name,
|
it = info.mutex_handles.emplace(name,
|
||||||
curr_prog::shm_data::init{name, sizeof(pthread_mutex_t)}).first;
|
curr_prog::shm_data::init{name, sizeof(pthread_mutex_t)}).first;
|
||||||
}
|
}
|
||||||
shm_ = &it->second.shm;
|
shm_ = &it->second.shm;
|
||||||
ref_ = &it->second.ref;
|
ref_ = &it->second.ref;
|
||||||
@ -69,13 +69,14 @@ class mutex {
|
|||||||
template <typename F>
|
template <typename F>
|
||||||
void release_mutex(ipc::string const &name, F &&clear) {
|
void release_mutex(ipc::string const &name, F &&clear) {
|
||||||
if (name.empty()) return;
|
if (name.empty()) return;
|
||||||
IPC_UNUSED_ std::lock_guard<std::mutex> guard {curr_prog::get().lock};
|
auto &info = curr_prog::get();
|
||||||
auto it = curr_prog::get().mutex_handles.find(name);
|
IPC_UNUSED_ std::lock_guard<std::mutex> guard {info.lock};
|
||||||
if (it == curr_prog::get().mutex_handles.end()) {
|
auto it = info.mutex_handles.find(name);
|
||||||
|
if (it == info.mutex_handles.end()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (clear()) {
|
if (clear()) {
|
||||||
curr_prog::get().mutex_handles.erase(it);
|
info.mutex_handles.erase(it);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -83,6 +84,11 @@ public:
|
|||||||
mutex() = default;
|
mutex() = default;
|
||||||
~mutex() = default;
|
~mutex() = default;
|
||||||
|
|
||||||
|
static void init() {
|
||||||
|
// Avoid exception problems caused by static member initialization order.
|
||||||
|
curr_prog::get();
|
||||||
|
}
|
||||||
|
|
||||||
pthread_mutex_t const *native() const noexcept {
|
pthread_mutex_t const *native() const noexcept {
|
||||||
return mutex_;
|
return mutex_;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -21,6 +21,8 @@ public:
|
|||||||
mutex() noexcept = default;
|
mutex() noexcept = default;
|
||||||
~mutex() noexcept = default;
|
~mutex() noexcept = default;
|
||||||
|
|
||||||
|
static void init() {}
|
||||||
|
|
||||||
HANDLE native() const noexcept {
|
HANDLE native() const noexcept {
|
||||||
return h_;
|
return h_;
|
||||||
}
|
}
|
||||||
|
|||||||
22
src/libipc/sync/waiter.cpp
Normal file
22
src/libipc/sync/waiter.cpp
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
#include "libipc/waiter.h"
|
||||||
|
|
||||||
|
#include "libipc/platform/detail.h"
|
||||||
|
#if defined(IPC_OS_WINDOWS_)
|
||||||
|
#include "libipc/platform/win/mutex.h"
|
||||||
|
#elif defined(IPC_OS_LINUX_)
|
||||||
|
#include "libipc/platform/linux/mutex.h"
|
||||||
|
#elif defined(IPC_OS_QNX_)
|
||||||
|
#include "libipc/platform/posix/mutex.h"
|
||||||
|
#else/*IPC_OS*/
|
||||||
|
# error "Unsupported platform."
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace ipc {
|
||||||
|
namespace detail {
|
||||||
|
|
||||||
|
void waiter::init() {
|
||||||
|
ipc::detail::sync::mutex::init();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
} // namespace ipc
|
||||||
@ -19,6 +19,8 @@ class waiter {
|
|||||||
std::atomic<bool> quit_ {false};
|
std::atomic<bool> quit_ {false};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
static void init();
|
||||||
|
|
||||||
waiter() = default;
|
waiter() = default;
|
||||||
waiter(char const *name) {
|
waiter(char const *name) {
|
||||||
open(name);
|
open(name);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user