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
162011d4b4
@ -19,6 +19,8 @@ enum : unsigned {
|
||||
|
||||
template <typename Flag>
|
||||
struct IPC_EXPORT chan_impl {
|
||||
static ipc::handle_t inited();
|
||||
|
||||
static bool connect (ipc::handle_t * ph, char const * name, unsigned mode);
|
||||
static bool reconnect (ipc::handle_t * ph, unsigned mode);
|
||||
static void disconnect(ipc::handle_t h);
|
||||
@ -41,7 +43,7 @@ class chan_wrapper {
|
||||
private:
|
||||
using detail_t = chan_impl<Flag>;
|
||||
|
||||
ipc::handle_t h_ = nullptr;
|
||||
ipc::handle_t h_ = detail_t::inited();
|
||||
unsigned mode_ = ipc::sender;
|
||||
bool connected_ = false;
|
||||
|
||||
|
||||
@ -630,6 +630,12 @@ using policy_t = ipc::policy::choose<ipc::circ::elem_array, Flag>;
|
||||
|
||||
namespace ipc {
|
||||
|
||||
template <typename Flag>
|
||||
ipc::handle_t chan_impl<Flag>::inited() {
|
||||
ipc::detail::waiter::init();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
template <typename Flag>
|
||||
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);
|
||||
|
||||
@ -125,7 +125,7 @@ class mutex {
|
||||
IPC_UNUSED_ std::lock_guard<std::mutex> guard {info.lock};
|
||||
auto it = info.mutex_handles.find(name);
|
||||
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;
|
||||
}
|
||||
mutex_ = &it->second.mtx;
|
||||
@ -135,13 +135,14 @@ class mutex {
|
||||
template <typename F>
|
||||
void release_mutex(ipc::string const &name, F &&clear) {
|
||||
if (name.empty()) return;
|
||||
IPC_UNUSED_ std::lock_guard<std::mutex> guard {curr_prog::get().lock};
|
||||
auto it = curr_prog::get().mutex_handles.find(name);
|
||||
if (it == curr_prog::get().mutex_handles.end()) {
|
||||
auto &info = curr_prog::get();
|
||||
IPC_UNUSED_ std::lock_guard<std::mutex> guard {info.lock};
|
||||
auto it = info.mutex_handles.find(name);
|
||||
if (it == info.mutex_handles.end()) {
|
||||
return;
|
||||
}
|
||||
if (clear()) {
|
||||
curr_prog::get().mutex_handles.erase(it);
|
||||
info.mutex_handles.erase(it);
|
||||
}
|
||||
}
|
||||
|
||||
@ -149,6 +150,11 @@ public:
|
||||
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 {
|
||||
return valid() ? mutex_->native() : nullptr;
|
||||
}
|
||||
|
||||
@ -55,7 +55,7 @@ class mutex {
|
||||
IPC_UNUSED_ std::lock_guard<std::mutex> guard {info.lock};
|
||||
auto it = info.mutex_handles.find(name);
|
||||
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;
|
||||
}
|
||||
shm_ = &it->second.shm;
|
||||
@ -69,13 +69,14 @@ class mutex {
|
||||
template <typename F>
|
||||
void release_mutex(ipc::string const &name, F &&clear) {
|
||||
if (name.empty()) return;
|
||||
IPC_UNUSED_ std::lock_guard<std::mutex> guard {curr_prog::get().lock};
|
||||
auto it = curr_prog::get().mutex_handles.find(name);
|
||||
if (it == curr_prog::get().mutex_handles.end()) {
|
||||
auto &info = curr_prog::get();
|
||||
IPC_UNUSED_ std::lock_guard<std::mutex> guard {info.lock};
|
||||
auto it = info.mutex_handles.find(name);
|
||||
if (it == info.mutex_handles.end()) {
|
||||
return;
|
||||
}
|
||||
if (clear()) {
|
||||
curr_prog::get().mutex_handles.erase(it);
|
||||
info.mutex_handles.erase(it);
|
||||
}
|
||||
}
|
||||
|
||||
@ -83,6 +84,11 @@ public:
|
||||
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 {
|
||||
return mutex_;
|
||||
}
|
||||
|
||||
@ -21,6 +21,8 @@ public:
|
||||
mutex() noexcept = default;
|
||||
~mutex() noexcept = default;
|
||||
|
||||
static void init() {}
|
||||
|
||||
HANDLE native() const noexcept {
|
||||
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};
|
||||
|
||||
public:
|
||||
static void init();
|
||||
|
||||
waiter() = default;
|
||||
waiter(char const *name) {
|
||||
open(name);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user