Optimized partial implementation using fmt

This commit is contained in:
mutouyun 2025-01-09 17:34:37 +08:00 committed by 木头云
parent a4361d2b97
commit 976610f914
10 changed files with 84 additions and 110 deletions

View File

@ -70,13 +70,13 @@ ipc::buff_t make_cache(T& data, std::size_t size) {
return { ptr, size, ipc::mem::free };
}
acc_t *cc_acc(ipc::string const &pref) {
static ipc::unordered_map<ipc::string, ipc::shm::handle> handles;
acc_t *cc_acc(std::string const &pref) {
static ipc::unordered_map<std::string, ipc::shm::handle> handles;
static std::mutex lock;
std::lock_guard<std::mutex> guard {lock};
auto it = handles.find(pref);
if (it == handles.end()) {
ipc::string shm_name {ipc::make_prefix(pref, {"CA_CONN__"})};
std::string shm_name {ipc::make_prefix(pref, "CA_CONN__")};
ipc::shm::handle h;
if (!h.acquire(shm_name.c_str(), sizeof(acc_t))) {
ipc::error("[cc_acc] acquire failed: %s\n", shm_name.c_str());
@ -105,8 +105,8 @@ struct cache_t {
struct conn_info_head {
ipc::string prefix_;
ipc::string name_;
std::string prefix_;
std::string name_;
msg_id_t cc_id_; // connection-info id
ipc::detail::waiter cc_waiter_, wt_waiter_, rd_waiter_;
ipc::shm::handle acc_h_;
@ -117,10 +117,10 @@ struct conn_info_head {
, cc_id_ {} {}
void init() {
if (!cc_waiter_.valid()) cc_waiter_.open(ipc::make_prefix(prefix_, {"CC_CONN__", name_}).c_str());
if (!wt_waiter_.valid()) wt_waiter_.open(ipc::make_prefix(prefix_, {"WT_CONN__", name_}).c_str());
if (!rd_waiter_.valid()) rd_waiter_.open(ipc::make_prefix(prefix_, {"RD_CONN__", name_}).c_str());
if (!acc_h_.valid()) acc_h_.acquire(ipc::make_prefix(prefix_, {"AC_CONN__", name_}).c_str(), sizeof(acc_t));
if (!cc_waiter_.valid()) cc_waiter_.open(ipc::make_prefix(prefix_, "CC_CONN__", name_).c_str());
if (!wt_waiter_.valid()) wt_waiter_.open(ipc::make_prefix(prefix_, "WT_CONN__", name_).c_str());
if (!rd_waiter_.valid()) rd_waiter_.open(ipc::make_prefix(prefix_, "RD_CONN__", name_).c_str());
if (!acc_h_.valid()) acc_h_.acquire(ipc::make_prefix(prefix_, "AC_CONN__", name_).c_str(), sizeof(acc_t));
if (cc_id_ != 0) {
return;
}
@ -146,10 +146,10 @@ struct conn_info_head {
static void clear_storage(char const * prefix, char const * name) noexcept {
auto p = ipc::make_string(prefix);
auto n = ipc::make_string(name);
ipc::detail::waiter::clear_storage(ipc::make_prefix(p, {"CC_CONN__", n}).c_str());
ipc::detail::waiter::clear_storage(ipc::make_prefix(p, {"WT_CONN__", n}).c_str());
ipc::detail::waiter::clear_storage(ipc::make_prefix(p, {"RD_CONN__", n}).c_str());
ipc::shm::handle::clear_storage(ipc::make_prefix(p, {"AC_CONN__", n}).c_str());
ipc::detail::waiter::clear_storage(ipc::make_prefix(p, "CC_CONN__", n).c_str());
ipc::detail::waiter::clear_storage(ipc::make_prefix(p, "WT_CONN__", n).c_str());
ipc::detail::waiter::clear_storage(ipc::make_prefix(p, "RD_CONN__", n).c_str());
ipc::shm::handle::clear_storage(ipc::make_prefix(p, "AC_CONN__", n).c_str());
}
void quit_waiting() {
@ -208,10 +208,10 @@ struct chunk_info_t {
auto& chunk_storages() {
class chunk_handle_t {
ipc::unordered_map<ipc::string, ipc::shm::handle> handles_;
ipc::unordered_map<std::string, ipc::shm::handle> handles_;
std::mutex lock_;
static bool make_handle(ipc::shm::handle &h, ipc::string const &shm_name, std::size_t chunk_size) {
static bool make_handle(ipc::shm::handle &h, std::string const &shm_name, std::size_t chunk_size) {
if (!h.valid() &&
!h.acquire( shm_name.c_str(),
sizeof(chunk_info_t) + chunk_info_t::chunks_mem_size(chunk_size) )) {
@ -223,8 +223,8 @@ auto& chunk_storages() {
public:
chunk_info_t *get_info(conn_info_head *inf, std::size_t chunk_size) {
ipc::string pref {(inf == nullptr) ? ipc::string{} : inf->prefix_};
ipc::string shm_name {ipc::make_prefix(pref, {"CHUNK_INFO__", ipc::to_string(chunk_size)})};
std::string pref {(inf == nullptr) ? std::string{} : inf->prefix_};
std::string shm_name {ipc::make_prefix(pref, "CHUNK_INFO__", chunk_size)};
ipc::shm::handle *h;
{
std::lock_guard<std::mutex> guard {lock_};
@ -394,11 +394,11 @@ struct queue_generator {
void init() {
conn_info_head::init();
if (!que_.valid()) {
que_.open(ipc::make_prefix(prefix_, {
que_.open(ipc::make_prefix(prefix_,
"QU_CONN__",
this->name_,
"__", ipc::to_string(DataSize),
"__", ipc::to_string(AlignSize)}).c_str());
"__", DataSize,
"__", AlignSize).c_str());
}
}
@ -408,11 +408,11 @@ struct queue_generator {
}
static void clear_storage(char const * prefix, char const * name) noexcept {
queue_t::clear_storage(ipc::make_prefix(ipc::make_string(prefix), {
queue_t::clear_storage(ipc::make_prefix(prefix,
"QU_CONN__",
ipc::make_string(name),
"__", ipc::to_string(DataSize),
"__", ipc::to_string(AlignSize)}).c_str());
name,
"__", DataSize,
"__", AlignSize).c_str());
conn_info_head::clear_storage(prefix, name);
}

View File

@ -14,6 +14,7 @@
#include "libipc/memory/alloc.h"
#include "libipc/memory/wrapper.h"
#include "libipc/platform/detail.h"
#include "libipc/imp/fmt.h"
namespace ipc {
namespace mem {
@ -31,20 +32,6 @@ using allocator = allocator_wrapper<T, async_pool_alloc>;
} // namespace mem
namespace {
constexpr char const * pf(int) { return "%d" ; }
constexpr char const * pf(long) { return "%ld" ; }
constexpr char const * pf(long long) { return "%lld"; }
constexpr char const * pf(unsigned int) { return "%u" ; }
constexpr char const * pf(unsigned long) { return "%lu" ; }
constexpr char const * pf(unsigned long long) { return "%llu"; }
constexpr char const * pf(float) { return "%f" ; }
constexpr char const * pf(double) { return "%f" ; }
constexpr char const * pf(long double) { return "%Lf" ; }
} // internal-linkage
template <typename T>
struct hash : public std::hash<T> {};
@ -78,33 +65,20 @@ template <> struct hash<wstring> {
}
};
template <typename T>
ipc::string to_string(T val) {
char buf[std::numeric_limits<T>::digits10 + 1] {};
if (std::snprintf(buf, sizeof(buf), pf(val), val) > 0) {
return buf;
}
return {};
}
/// \brief Check string validity.
constexpr bool is_valid_string(char const *str) noexcept {
return (str != nullptr) && (str[0] != '\0');
}
/// \brief Make a valid string.
inline ipc::string make_string(char const *str) {
return is_valid_string(str) ? ipc::string{str} : ipc::string{};
inline std::string make_string(char const *str) {
return is_valid_string(str) ? std::string{str} : std::string{};
}
/// \brief Combine prefix from a list of strings.
inline ipc::string make_prefix(ipc::string prefix, std::initializer_list<ipc::string> args) {
prefix += "__IPC_SHM__";
for (auto const &txt: args) {
if (txt.empty()) continue;
prefix += txt;
}
return prefix;
template <typename... A>
inline std::string make_prefix(std::string prefix, A &&...args) {
return ipc::fmt(prefix, "__IPC_SHM__", std::forward<A>(args)...);
}
} // namespace ipc

View File

@ -108,7 +108,7 @@ class mutex {
shm_data(init arg)
: mtx{}, ref{0} { mtx.open(arg.name); }
};
ipc::map<ipc::string, shm_data> mutex_handles;
ipc::map<std::string, shm_data> mutex_handles;
std::mutex lock;
static curr_prog &get() {
@ -136,7 +136,7 @@ class mutex {
}
template <typename F>
static void release_mutex(ipc::string const &name, F &&clear) {
static void release_mutex(std::string const &name, F &&clear) {
if (name.empty()) return;
auto &info = curr_prog::get();
LIBIPC_UNUSED std::lock_guard<std::mutex> guard {info.lock};

View File

@ -38,7 +38,7 @@ class mutex {
shm_data(init arg)
: shm{arg.name, arg.size}, ref{0} {}
};
ipc::map<ipc::string, shm_data> mutex_handles;
ipc::map<std::string, shm_data> mutex_handles;
std::mutex lock;
static curr_prog &get() {
@ -71,7 +71,7 @@ class mutex {
}
template <typename F>
static void release_mutex(ipc::string const &name, F &&clear) {
static void release_mutex(std::string const &name, F &&clear) {
if (name.empty()) return;
auto &info = curr_prog::get();
LIBIPC_UNUSED std::lock_guard<std::mutex> guard {info.lock};

View File

@ -28,7 +28,7 @@ struct id_info_t {
int fd_ = -1;
void* mem_ = nullptr;
std::size_t size_ = 0;
ipc::string name_;
std::string name_;
};
constexpr std::size_t calc_size(std::size_t size) {
@ -51,7 +51,7 @@ id_t acquire(char const * name, std::size_t size, unsigned mode) {
}
// For portable use, a shared memory object should be identified by name of the form /somename.
// see: https://man7.org/linux/man-pages/man3/shm_open.3.html
ipc::string op_name = ipc::string{"/"} + name;
std::string op_name = std::string{"/"} + name;
// Open the object for read-write access.
int flag = O_RDWR;
switch (mode) {

View File

@ -40,7 +40,7 @@ using IsSameChar = ipc::require<is_same_char<T, S>::value, R>;
////////////////////////////////////////////////////////////////
template <typename T = TCHAR>
constexpr auto to_tchar(ipc::string &&str) -> IsSameChar<T, ipc::string, ipc::string &&> {
constexpr auto to_tchar(std::string &&str) -> IsSameChar<T, std::string, std::string &&> {
return std::move(str); // noconv
}
@ -52,7 +52,7 @@ constexpr auto to_tchar(ipc::string &&str) -> IsSameChar<T, ipc::string, ipc::st
* https://docs.microsoft.com/en-us/windows/win32/api/stringapiset/nf-stringapiset-multibytetowidechar
*/
template <typename T = TCHAR>
auto to_tchar(ipc::string &&external) -> IsSameChar<T, ipc::wstring> {
auto to_tchar(std::string &&external) -> IsSameChar<T, std::wstring> {
if (external.empty()) {
return {}; // noconv
}
@ -69,7 +69,7 @@ auto to_tchar(ipc::string &&external) -> IsSameChar<T, ipc::wstring> {
if (size_needed <= 0) {
return {};
}
ipc::wstring internal(size_needed, L'\0');
std::wstring internal(size_needed, L'\0');
::MultiByteToWideChar(CP_UTF8, 0, &external[0], (int)external.size(), &internal[0], size_needed);
return internal;
}

View File

@ -16,7 +16,7 @@ public:
shm::id_t id_ = nullptr;
void* m_ = nullptr;
ipc::string n_;
std::string n_;
std::size_t s_ = 0;
};

View File

@ -17,11 +17,11 @@ TEST(Platform, to_tchar) {
"\x81\xab\xe3\x81\xa1\xe3\x81\xaf";
wchar_t const *utf16 = L"hello world, \u4f60\u597d\uff0c\u3053\u3093\u306b\u3061\u306f";
{
ipc::string str = ipc::detail::to_tchar<char>(utf8);
std::string str = ipc::detail::to_tchar<char>(utf8);
EXPECT_STREQ(str.c_str(), utf8);
}
{
ipc::wstring wtr = ipc::detail::to_tchar<wchar_t>(utf8);
std::wstring wtr = ipc::detail::to_tchar<wchar_t>(utf8);
EXPECT_STREQ(wtr.c_str(), utf16);
//std::ofstream out("out.txt", std::ios::binary|std::ios::out);
//out.write((char const *)wtr.c_str(), wtr.size() * sizeof(wchar_t));

View File

@ -8,6 +8,7 @@
#include "libipc/imp/fmt.h"
#include "libipc/imp/byte.h"
#include "libipc/imp/span.h"
#include "libipc/imp/result.h"
TEST(fmt, spec) {
EXPECT_STREQ(ipc::spec("hello")(123).fstr.data(), "hello");
@ -143,3 +144,44 @@ TEST(fmt, span) {
EXPECT_EQ(ipc::fmt(ipc::span<int>{}), "");
EXPECT_EQ(ipc::fmt(ipc::make_span({1, 3, 2, 4, 5, 6, 7})), "1 3 2 4 5 6 7");
}
TEST(fmt, result) {
{
ipc::result<std::uint64_t> r1;
EXPECT_EQ(ipc::fmt(r1), ipc::fmt("fail, error = ", std::error_code(-1, std::generic_category())));
ipc::result<std::uint64_t> r2(65537);
EXPECT_EQ(ipc::fmt(r2), "succ, value = 65537");
ipc::result<std::uint64_t> r3(0);
EXPECT_EQ(ipc::fmt(r3), "succ, value = 0");
}
{
ipc::result<int> r0;
EXPECT_EQ(ipc::fmt(r0), ipc::fmt(ipc::result<std::uint64_t>()));
ipc::result<int> r1 {std::error_code(-1, std::generic_category())};
EXPECT_EQ(ipc::fmt(r1), ipc::fmt("fail, error = ", std::error_code(-1, std::generic_category())));
ipc::result<void *> r2 {&r1};
EXPECT_EQ(ipc::fmt(r2), ipc::fmt("succ, value = ", (void *)&r1));
int aaa {};
ipc::result<int *> r3 {&aaa};
EXPECT_EQ(ipc::fmt(r3), ipc::fmt("succ, value = ", (void *)&aaa));
ipc::result<int *> r4 {nullptr};
EXPECT_EQ(ipc::fmt(r4), ipc::fmt("fail, error = ", std::error_code(-1, std::generic_category())));
r4 = std::error_code(1234, std::generic_category());
EXPECT_EQ(ipc::fmt(r4), ipc::fmt("fail, error = ", std::error_code(1234, std::generic_category())));
ipc::result<int *> r5;
EXPECT_EQ(ipc::fmt(r5), ipc::fmt("fail, error = ", std::error_code(-1, std::generic_category())));
}
{
ipc::result<std::int64_t> r1 {-123};
EXPECT_EQ(ipc::fmt(r1), ipc::fmt("succ, value = ", -123));
}
{
ipc::result<void> r1;
EXPECT_EQ(ipc::fmt(r1), ipc::fmt("fail, error = ", std::error_code(-1, std::generic_category())));
r1 = std::error_code{};
EXPECT_TRUE(r1);
EXPECT_EQ(ipc::fmt(r1), ipc::fmt("succ, error = ", std::error_code()));
}
}

View File

@ -5,7 +5,6 @@
#include "test.h"
#include "libipc/imp/result.h"
#include "libipc/imp/fmt.h"
TEST(result, ok) {
ipc::result<std::uint64_t> ret;
@ -66,44 +65,3 @@ TEST(result, compare) {
r3 = r5;
EXPECT_EQ(r3, r5);
}
TEST(result, fmt) {
{
ipc::result<std::uint64_t> r1;
EXPECT_EQ(ipc::fmt(r1), ipc::fmt("fail, error = ", std::error_code(-1, std::generic_category())));
ipc::result<std::uint64_t> r2(65537);
EXPECT_EQ(ipc::fmt(r2), "succ, value = 65537");
ipc::result<std::uint64_t> r3(0);
EXPECT_EQ(ipc::fmt(r3), "succ, value = 0");
}
{
ipc::result<int> r0;
EXPECT_EQ(ipc::fmt(r0), ipc::fmt(ipc::result<std::uint64_t>()));
ipc::result<int> r1 {std::error_code(-1, std::generic_category())};
EXPECT_EQ(ipc::fmt(r1), ipc::fmt("fail, error = ", std::error_code(-1, std::generic_category())));
ipc::result<void *> r2 {&r1};
EXPECT_EQ(ipc::fmt(r2), ipc::fmt("succ, value = ", (void *)&r1));
int aaa {};
ipc::result<int *> r3 {&aaa};
EXPECT_EQ(ipc::fmt(r3), ipc::fmt("succ, value = ", (void *)&aaa));
ipc::result<int *> r4 {nullptr};
EXPECT_EQ(ipc::fmt(r4), ipc::fmt("fail, error = ", std::error_code(-1, std::generic_category())));
r4 = std::error_code(1234, std::generic_category());
EXPECT_EQ(ipc::fmt(r4), ipc::fmt("fail, error = ", std::error_code(1234, std::generic_category())));
ipc::result<int *> r5;
EXPECT_EQ(ipc::fmt(r5), ipc::fmt("fail, error = ", std::error_code(-1, std::generic_category())));
}
{
ipc::result<std::int64_t> r1 {-123};
EXPECT_EQ(ipc::fmt(r1), ipc::fmt("succ, value = ", -123));
}
{
ipc::result<void> r1;
EXPECT_EQ(ipc::fmt(r1), ipc::fmt("fail, error = ", std::error_code(-1, std::generic_category())));
r1 = std::error_code{};
EXPECT_TRUE(r1);
EXPECT_EQ(ipc::fmt(r1), ipc::fmt("succ, error = ", std::error_code()));
}
}