修正全局变量初始化时序问题导致的内存访问异常

This commit is contained in:
mutouyun 2023-02-11 18:08:55 +08:00
parent 768e58f605
commit 9ac32df68d
7 changed files with 59 additions and 13 deletions

View File

@ -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;

View File

@ -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);

View File

@ -125,8 +125,8 @@ 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,
curr_prog::shm_data::init{name}).first;
it = info.mutex_handles.emplace(name,
curr_prog::shm_data::init{name}).first;
}
mutex_ = &it->second.mtx;
ref_ = &it->second.ref;
@ -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;
}

View File

@ -55,8 +55,8 @@ 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,
curr_prog::shm_data::init{name, sizeof(pthread_mutex_t)}).first;
it = info.mutex_handles.emplace(name,
curr_prog::shm_data::init{name, sizeof(pthread_mutex_t)}).first;
}
shm_ = &it->second.shm;
ref_ = &it->second.ref;
@ -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_;
}

View File

@ -21,6 +21,8 @@ public:
mutex() noexcept = default;
~mutex() noexcept = default;
static void init() {}
HANDLE native() const noexcept {
return h_;
}

View 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

View File

@ -19,6 +19,8 @@ class waiter {
std::atomic<bool> quit_ {false};
public:
static void init();
waiter() = default;
waiter(char const *name) {
open(name);