mirror of
https://github.com/mutouyun/cpp-ipc.git
synced 2025-12-07 01:06:45 +08:00
invalid large message storage
This commit is contained in:
parent
cf0028bf09
commit
0beb0b4a13
53
src/ipc.cpp
Normal file → Executable file
53
src/ipc.cpp
Normal file → Executable file
@ -42,18 +42,13 @@ struct msg_t<0, AlignSize> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
template <std::size_t DataSize, std::size_t AlignSize>
|
template <std::size_t DataSize, std::size_t AlignSize>
|
||||||
struct msg_t {
|
struct msg_t : msg_t<0, AlignSize> {
|
||||||
msg_t<0, AlignSize> head_ { 0, 0, 0, false };
|
|
||||||
std::aligned_storage_t<DataSize, AlignSize> data_ {};
|
std::aligned_storage_t<DataSize, AlignSize> data_ {};
|
||||||
|
|
||||||
msg_t() = default;
|
msg_t() = default;
|
||||||
msg_t(msg_id_t c, msg_id_t i, int r, void const * d, std::size_t s)
|
msg_t(msg_id_t c, msg_id_t i, int r, void const * d, std::size_t s)
|
||||||
: head_ { c, i, r, false } {
|
: msg_t<0, AlignSize> { c, i, r, (d == nullptr) || (s == 0) } {
|
||||||
if (d != nullptr) {
|
if (!this->storage_) {
|
||||||
if (s == 0) {
|
|
||||||
head_.storage_ = true;
|
|
||||||
s = sizeof(msg_id_t);
|
|
||||||
}
|
|
||||||
std::memcpy(&data_, d, s);
|
std::memcpy(&data_, d, s);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -144,12 +139,16 @@ struct conn_info_head {
|
|||||||
return *recv_cache_.create();
|
return *recv_cache_.create();
|
||||||
}
|
}
|
||||||
|
|
||||||
static shm::id_t apply_storage(msg_id_t msg_id, std::size_t size) {
|
shm::id_t apply_storage(msg_id_t msg_id, std::size_t size) {
|
||||||
return shm::acquire(("__ST_CONN__" + ipc::to_string(msg_id)).c_str(), size, shm::create);
|
return shm::acquire(
|
||||||
|
("__ST_CONN__" + ipc::to_string(cc_id_) +
|
||||||
|
"__" + ipc::to_string(msg_id)).c_str(), size, shm::create);
|
||||||
}
|
}
|
||||||
|
|
||||||
static shm::id_t apply_storage(msg_id_t msg_id) {
|
static shm::id_t acquire_storage(msg_id_t cc_id, msg_id_t msg_id) {
|
||||||
return shm::acquire(("__ST_CONN__" + ipc::to_string(msg_id)).c_str(), 0, shm::open);
|
return shm::acquire(
|
||||||
|
("__ST_CONN__" + ipc::to_string(cc_id) +
|
||||||
|
"__" + ipc::to_string(msg_id)).c_str(), 0, shm::open);
|
||||||
}
|
}
|
||||||
|
|
||||||
void store(shm::id_t dat) {
|
void store(shm::id_t dat) {
|
||||||
@ -207,8 +206,8 @@ struct queue_generator {
|
|||||||
template <typename Policy>
|
template <typename Policy>
|
||||||
struct detail_impl {
|
struct detail_impl {
|
||||||
|
|
||||||
using queue_t = typename queue_generator<Policy, data_length>::queue_t;
|
using queue_t = typename queue_generator<Policy>::queue_t;
|
||||||
using conn_info_t = typename queue_generator<Policy, data_length>::conn_info_t;
|
using conn_info_t = typename queue_generator<Policy>::conn_info_t;
|
||||||
|
|
||||||
constexpr static conn_info_t* info_of(ipc::handle_t h) {
|
constexpr static conn_info_t* info_of(ipc::handle_t h) {
|
||||||
return static_cast<conn_info_t*>(h);
|
return static_cast<conn_info_t*>(h);
|
||||||
@ -362,34 +361,34 @@ static buff_t recv(ipc::handle_t h, std::size_t tm) {
|
|||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
info_of(h)->wt_waiter_.broadcast();
|
info_of(h)->wt_waiter_.broadcast();
|
||||||
if ((info_of(h)->acc() != nullptr) && (msg.head_.conn_ == info_of(h)->cc_id_)) {
|
if ((info_of(h)->acc() != nullptr) && (msg.conn_ == info_of(h)->cc_id_)) {
|
||||||
continue; // ignore message to self
|
continue; // ignore message to self
|
||||||
}
|
}
|
||||||
// msg.head_.remain_ may minus & abs(msg.head_.remain_) < data_length
|
// msg.remain_ may minus & abs(msg.remain_) < data_length
|
||||||
auto remain = static_cast<std::size_t>(static_cast<int>(data_length) + msg.head_.remain_);
|
auto remain = static_cast<std::size_t>(static_cast<int>(data_length) + msg.remain_);
|
||||||
// find cache with msg.head_.id_
|
// find cache with msg.id_
|
||||||
auto cac_it = rc.find(msg.head_.id_);
|
auto cac_it = rc.find(msg.id_);
|
||||||
if (cac_it == rc.end()) {
|
if (cac_it == rc.end()) {
|
||||||
if (remain <= data_length) {
|
if (remain <= data_length) {
|
||||||
return make_cache(msg.data_, remain);
|
return make_cache(msg.data_, remain);
|
||||||
}
|
}
|
||||||
if (msg.head_.storage_) {
|
if (msg.storage_) {
|
||||||
auto dat = info_of(h)->apply_storage(msg.head_.id_);
|
auto dat = info_of(h)->acquire_storage(msg.conn_, msg.id_);
|
||||||
std::size_t dat_sz = 0;
|
std::size_t dat_sz = 0;
|
||||||
void * buf = shm::get_mem(dat, &dat_sz);
|
void * buf = shm::get_mem(dat, &dat_sz);
|
||||||
if (buf != nullptr && remain <= dat_sz) {
|
if (buf != nullptr && remain <= dat_sz) {
|
||||||
return buff_t { buf, remain, [](void * p, std::size_t) {
|
return buff_t { buf, remain, [](void * dat, std::size_t) {
|
||||||
shm::release(p);
|
shm::release(dat);
|
||||||
}, dat };
|
}, dat };
|
||||||
}
|
}
|
||||||
else ipc::log("fail: shm::handle for big message. msg_id: %zd, size: %zd, shm.size: %zd\n",
|
else ipc::log("fail: shm::handle for big message. msg_id: %zd, size: %zd, shm.size: %zd\n",
|
||||||
msg.head_.id_, remain, dat_sz);
|
msg.id_, remain, dat_sz);
|
||||||
}
|
}
|
||||||
// gc
|
// gc
|
||||||
if (rc.size() > 1024) {
|
if (rc.size() > 1024) {
|
||||||
std::vector<msg_id_t> need_del;
|
std::vector<msg_id_t> need_del;
|
||||||
for (auto const & pair : rc) {
|
for (auto const & pair : rc) {
|
||||||
auto cmp = std::minmax(msg.head_.id_, pair.first);
|
auto cmp = std::minmax(msg.id_, pair.first);
|
||||||
if (cmp.second - cmp.first > 8192) {
|
if (cmp.second - cmp.first > 8192) {
|
||||||
need_del.push_back(pair.first);
|
need_del.push_back(pair.first);
|
||||||
}
|
}
|
||||||
@ -397,13 +396,13 @@ static buff_t recv(ipc::handle_t h, std::size_t tm) {
|
|||||||
for (auto id : need_del) rc.erase(id);
|
for (auto id : need_del) rc.erase(id);
|
||||||
}
|
}
|
||||||
// cache the first message fragment
|
// cache the first message fragment
|
||||||
rc.emplace(msg.head_.id_, cache_t { data_length, make_cache(msg.data_, remain) });
|
rc.emplace(msg.id_, cache_t { data_length, make_cache(msg.data_, remain) });
|
||||||
}
|
}
|
||||||
// has cached before this message
|
// has cached before this message
|
||||||
else {
|
else {
|
||||||
auto& cac = cac_it->second;
|
auto& cac = cac_it->second;
|
||||||
// this is the last message fragment
|
// this is the last message fragment
|
||||||
if (msg.head_.remain_ <= 0) {
|
if (msg.remain_ <= 0) {
|
||||||
cac.append(&(msg.data_), remain);
|
cac.append(&(msg.data_), remain);
|
||||||
// finish this message, erase it from cache
|
// finish this message, erase it from cache
|
||||||
auto buff = std::move(cac.buff_);
|
auto buff = std::move(cac.buff_);
|
||||||
|
|||||||
10
src/memory/resource.h
Normal file → Executable file
10
src/memory/resource.h
Normal file → Executable file
@ -50,13 +50,13 @@ using unordered_map = std::unordered_map<
|
|||||||
Key, T, std::hash<Key>, std::equal_to<Key>, ipc::mem::allocator<std::pair<const Key, T>>
|
Key, T, std::hash<Key>, std::equal_to<Key>, ipc::mem::allocator<std::pair<const Key, T>>
|
||||||
>;
|
>;
|
||||||
|
|
||||||
using string = std::basic_string<
|
template <typename Char>
|
||||||
char, std::char_traits<char>, ipc::mem::allocator<char>
|
using basic_string = std::basic_string<
|
||||||
|
Char, std::char_traits<Char>, ipc::mem::allocator<Char>
|
||||||
>;
|
>;
|
||||||
|
|
||||||
using wstring = std::basic_string<
|
using string = basic_string<char>;
|
||||||
wchar_t, std::char_traits<wchar_t>, ipc::mem::allocator<wchar_t>
|
using wstring = basic_string<wchar_t>;
|
||||||
>;
|
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
ipc::string to_string(T val) {
|
ipc::string to_string(T val) {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user