mirror of
https://github.com/mutouyun/cpp-ipc.git
synced 2025-12-07 01:06:45 +08:00
shm would fail with multi-thread accessing
This commit is contained in:
parent
219e9375ce
commit
7e44b2dd4d
@ -8,8 +8,9 @@
|
|||||||
|
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <utility>
|
||||||
|
#include <mutex>
|
||||||
|
|
||||||
#include "tls_pointer.h"
|
|
||||||
#include "memory/resource.hpp"
|
#include "memory/resource.hpp"
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
@ -24,9 +25,12 @@ constexpr void* mem_of(void* mem) {
|
|||||||
return static_cast<acc_t*>(mem) - 1;
|
return static_cast<acc_t*>(mem) - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline auto& m2h() {
|
inline auto* m2h() {
|
||||||
static ipc::tls::pointer<ipc::mem::unordered_map<void*, std::string>> cache;
|
static struct {
|
||||||
return *cache.create();
|
std::mutex lc_;
|
||||||
|
ipc::mem::unordered_map<void*, std::string> cache_;
|
||||||
|
} m2h_;
|
||||||
|
return &m2h_;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // internal-linkage
|
} // internal-linkage
|
||||||
@ -38,29 +42,32 @@ void* acquire(char const * name, std::size_t size) {
|
|||||||
if (name == nullptr || name[0] == '\0' || size == 0) {
|
if (name == nullptr || name[0] == '\0' || size == 0) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
int fd = ::shm_open((std::string{"__IPC_SHM__"} + name).c_str(),
|
std::string op_name = std::string{"__IPC_SHM__"} + name;
|
||||||
O_CREAT | O_RDWR,
|
int fd = ::shm_open(op_name.c_str(), O_CREAT | O_RDWR,
|
||||||
S_IRUSR | S_IWUSR |
|
S_IRUSR | S_IWUSR |
|
||||||
S_IRGRP | S_IWGRP |
|
S_IRGRP | S_IWGRP |
|
||||||
S_IROTH | S_IWOTH);
|
S_IROTH | S_IWOTH);
|
||||||
if (fd == -1) {
|
if (fd == -1) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
size += sizeof(acc_t);
|
size += sizeof(acc_t);
|
||||||
if (::ftruncate(fd, static_cast<off_t>(size)) != 0) {
|
if (::ftruncate(fd, static_cast<off_t>(size)) != 0) {
|
||||||
::close(fd);
|
::close(fd);
|
||||||
::shm_unlink(name);
|
::shm_unlink(op_name.c_str());
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
void* mem = ::mmap(nullptr, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
|
void* mem = ::mmap(nullptr, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
|
||||||
::close(fd);
|
::close(fd);
|
||||||
if (mem == MAP_FAILED) {
|
if (mem == MAP_FAILED) {
|
||||||
::shm_unlink(name);
|
::shm_unlink(op_name.c_str());
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
auto acc = acc_of(mem);
|
auto acc = acc_of(mem);
|
||||||
acc->fetch_add(1, std::memory_order_release);
|
acc->fetch_add(1, std::memory_order_release);
|
||||||
m2h().emplace(++acc, name);
|
{
|
||||||
|
[[maybe_unused]] auto guard = std::unique_lock { m2h()->lc_ };
|
||||||
|
m2h()->cache_.emplace(++acc, std::move(op_name));
|
||||||
|
}
|
||||||
return acc;
|
return acc;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -68,7 +75,8 @@ void release(void* mem, std::size_t size) {
|
|||||||
if (mem == nullptr) {
|
if (mem == nullptr) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
auto& cc = m2h();
|
[[maybe_unused]] auto guard = std::unique_lock { m2h()->lc_ };
|
||||||
|
auto& cc = m2h()->cache_;
|
||||||
auto it = cc.find(mem);
|
auto it = cc.find(mem);
|
||||||
if (it == cc.end()) {
|
if (it == cc.end()) {
|
||||||
return;
|
return;
|
||||||
|
|||||||
@ -17,6 +17,8 @@ class Unit : public TestSuite {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
|
void cleanupTestCase();
|
||||||
|
|
||||||
void test_acquire();
|
void test_acquire();
|
||||||
void test_release();
|
void test_release();
|
||||||
void test_get();
|
void test_get();
|
||||||
@ -28,6 +30,10 @@ private slots:
|
|||||||
|
|
||||||
handle shm_hd__;
|
handle shm_hd__;
|
||||||
|
|
||||||
|
void Unit::cleanupTestCase() {
|
||||||
|
shm_hd__.release();
|
||||||
|
}
|
||||||
|
|
||||||
void Unit::test_acquire() {
|
void Unit::test_acquire() {
|
||||||
QVERIFY(!shm_hd__.valid());
|
QVERIFY(!shm_hd__.valid());
|
||||||
|
|
||||||
@ -97,6 +103,10 @@ void Unit::test_mt() {
|
|||||||
}.join();
|
}.join();
|
||||||
QVERIFY(shm_hd__.get() == nullptr);
|
QVERIFY(shm_hd__.get() == nullptr);
|
||||||
QVERIFY(!shm_hd__.valid());
|
QVERIFY(!shm_hd__.valid());
|
||||||
|
|
||||||
|
QVERIFY(shm_hd__.acquire("my-test", 1024));
|
||||||
|
std::uint8_t buf[1024] = {};
|
||||||
|
QVERIFY(memcmp(shm_hd__.get(), buf, sizeof(buf)) == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // internal-linkage
|
} // internal-linkage
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user