mirror of
https://github.com/mutouyun/cpp-ipc.git
synced 2025-12-07 01:06:45 +08:00
upd: [imp] improve interface of result
This commit is contained in:
parent
0a88c53aeb
commit
94cae29b42
@ -27,7 +27,8 @@ class LIBIMP_EXPORT result_code {
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
result_code() noexcept;
|
result_code() noexcept;
|
||||||
result_code(bool ok, std::uint64_t value = {}) noexcept;
|
result_code(std::uint64_t value) noexcept;
|
||||||
|
result_code(bool ok, std::uint64_t value) noexcept;
|
||||||
|
|
||||||
std::uint64_t value() const noexcept;
|
std::uint64_t value() const noexcept;
|
||||||
bool ok() const noexcept;
|
bool ok() const noexcept;
|
||||||
@ -103,7 +104,11 @@ public:
|
|||||||
using default_traits_t = DefTraits;
|
using default_traits_t = DefTraits;
|
||||||
|
|
||||||
result() noexcept = default;
|
result() noexcept = default;
|
||||||
result(bool ok, T value = default_traits_t::value()) noexcept
|
|
||||||
|
result(T value) noexcept
|
||||||
|
: result(true, std::move(value)) {}
|
||||||
|
|
||||||
|
result(bool ok, T value) noexcept
|
||||||
: code_(ok, default_traits_t::cast_to_code(value)) {}
|
: code_(ok, default_traits_t::cast_to_code(value)) {}
|
||||||
|
|
||||||
T value() const noexcept { return default_traits_t::cast_from_code(code_.value()); }
|
T value() const noexcept { return default_traits_t::cast_from_code(code_.value()); }
|
||||||
|
|||||||
@ -21,7 +21,10 @@ result_code_info info_cast(std::uint64_t status) noexcept {
|
|||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
result_code::result_code() noexcept
|
result_code::result_code() noexcept
|
||||||
: result_code(false) {}
|
: result_code(false, {}) {}
|
||||||
|
|
||||||
|
result_code::result_code(std::uint64_t value) noexcept
|
||||||
|
: result_code(true, value) {}
|
||||||
|
|
||||||
result_code::result_code(bool ok, std::uint64_t code) noexcept
|
result_code::result_code(bool ok, std::uint64_t code) noexcept
|
||||||
: status_(make_status(ok, code)) {}
|
: status_(make_status(ok, code)) {}
|
||||||
|
|||||||
@ -10,6 +10,7 @@ LIBIPC_NAMESPACE_BEG_
|
|||||||
namespace posix {
|
namespace posix {
|
||||||
|
|
||||||
enum : int {
|
enum : int {
|
||||||
|
succ = 0,
|
||||||
failed = -1,
|
failed = -1,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -31,13 +31,23 @@ struct shm_handle {
|
|||||||
void *memp;
|
void *memp;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
namespace {
|
||||||
* @see https://man7.org/linux/man-pages/man3/shm_open.3.html
|
|
||||||
* https://man7.org/linux/man-pages/man3/fstat.3p.html
|
shm_handle *valid(shm_t h) noexcept {
|
||||||
* https://man7.org/linux/man-pages/man3/ftruncate.3p.html
|
LIBIMP_LOG_();
|
||||||
* https://man7.org/linux/man-pages/man2/mmap.2.html
|
if (h == nullptr) {
|
||||||
*/
|
log.error("shm handle is null.");
|
||||||
result<shm_t> shm_open(std::string name, std::size_t size, mode::type type) noexcept {
|
return nullptr;
|
||||||
|
}
|
||||||
|
auto shm = static_cast<shm_handle *>(h);
|
||||||
|
if (shm->memp == nullptr) {
|
||||||
|
log.error("memory pointer is null.");
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
return shm;
|
||||||
|
}
|
||||||
|
|
||||||
|
result<int> shm_open_fd(std::string const &name, mode::type type) noexcept {
|
||||||
LIBIMP_LOG_();
|
LIBIMP_LOG_();
|
||||||
if (name.empty()) {
|
if (name.empty()) {
|
||||||
log.error("name is empty.");
|
log.error("name is empty.");
|
||||||
@ -48,7 +58,6 @@ result<shm_t> shm_open(std::string name, std::size_t size, mode::type type) noex
|
|||||||
int flag = O_RDWR;
|
int flag = O_RDWR;
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case mode::open:
|
case mode::open:
|
||||||
size = 0;
|
|
||||||
break;
|
break;
|
||||||
// The check for the existence of the object,
|
// The check for the existence of the object,
|
||||||
// and its creation if it does not exist, are performed atomically.
|
// and its creation if it does not exist, are performed atomically.
|
||||||
@ -65,50 +74,64 @@ result<shm_t> shm_open(std::string name, std::size_t size, mode::type type) noex
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// @brief Create/Open POSIX shared memory bject
|
/// @brief Create/Open POSIX shared memory bject
|
||||||
int fd = ::shm_open(name.c_str(), flag, S_IRUSR | S_IWUSR |
|
return ::shm_open(name.c_str(), flag, S_IRUSR | S_IWUSR |
|
||||||
S_IRGRP | S_IWGRP |
|
S_IRGRP | S_IWGRP |
|
||||||
S_IROTH | S_IWOTH);
|
S_IROTH | S_IWOTH);
|
||||||
if (fd == posix::failed) {
|
}
|
||||||
|
|
||||||
|
result_code ftruncate_fd(int fd, std::size_t size) noexcept {
|
||||||
|
LIBIMP_LOG_();
|
||||||
|
/// @see https://man7.org/linux/man-pages/man3/ftruncate.3p.html
|
||||||
|
if (::ftruncate(fd, size) != posix::succ) {
|
||||||
|
auto err = sys::error();
|
||||||
|
log.error("ftruncate({}, {}) fails. error = {}", fd, size, err);
|
||||||
|
return err.code();
|
||||||
|
}
|
||||||
|
return {posix::succ};
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see https://man7.org/linux/man-pages/man3/shm_open.3.html
|
||||||
|
* https://man7.org/linux/man-pages/man3/fstat.3p.html
|
||||||
|
* https://man7.org/linux/man-pages/man2/mmap.2.html
|
||||||
|
*/
|
||||||
|
result<shm_t> shm_open(std::string name, std::size_t size, mode::type type) noexcept {
|
||||||
|
LIBIMP_LOG_();
|
||||||
|
auto fd = shm_open_fd(name, type);
|
||||||
|
if (!fd) return {};
|
||||||
|
if (*fd == posix::failed) {
|
||||||
log.error("shm_open fails. error = {}", sys::error());
|
log.error("shm_open fails. error = {}", sys::error());
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
LIBIMP_UNUSED auto guard = std::unique_ptr<int, void (*)(int *)>(&fd, [](int *pfd) {
|
LIBIMP_UNUSED auto guard = std::unique_ptr<decltype(fd), void (*)(decltype(fd) *)> {
|
||||||
if (pfd != nullptr) ::close(*pfd);
|
&fd, [](decltype(fd) *pfd) {
|
||||||
});
|
if (pfd != nullptr) ::close(**pfd);
|
||||||
|
}};
|
||||||
|
|
||||||
/// @brief Try to get the size of this fd
|
/// @brief Try to get the size of this fd
|
||||||
struct stat st;
|
struct stat st;
|
||||||
if (::fstat(fd, &st) == posix::failed) {
|
if (::fstat(*fd, &st) == posix::failed) {
|
||||||
log.error("fstat fails. error = {}", sys::error());
|
log.error("fstat fails. error = {}", sys::error());
|
||||||
::shm_unlink(name.c_str());
|
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @brief Truncate this fd to a specified length
|
/// @brief Truncate this fd to a specified length
|
||||||
auto ftruncate = [&log, &name](int fd, std::size_t size) {
|
|
||||||
if (::ftruncate(fd, size) != 0) {
|
|
||||||
log.error("ftruncate fails. error = {}", sys::error());
|
|
||||||
::shm_unlink(name.c_str());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
};
|
|
||||||
|
|
||||||
if (size == 0) {
|
if (size == 0) {
|
||||||
size = static_cast<std::size_t>(st.st_size);
|
size = static_cast<std::size_t>(st.st_size);
|
||||||
if (!ftruncate(fd, size)) return {};
|
if (!ftruncate_fd(*fd, size)) return {};
|
||||||
} else if (st.st_size > 0) {
|
} else if (st.st_size > 0) {
|
||||||
/// @remark Based on the actual size.
|
/// @remark Based on the actual size.
|
||||||
size = static_cast<std::size_t>(st.st_size);
|
size = static_cast<std::size_t>(st.st_size);
|
||||||
} else { // st.st_size <= 0
|
} else { // st.st_size <= 0
|
||||||
if (!ftruncate(fd, size)) return {};
|
if (!ftruncate_fd(*fd, size)) return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @brief Creates a new mapping in the virtual address space of the calling process.
|
/// @brief Creates a new mapping in the virtual address space of the calling process.
|
||||||
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);
|
||||||
if (mem == MAP_FAILED) {
|
if (mem == MAP_FAILED) {
|
||||||
log.error("mmap fails. error = {}", sys::error());
|
log.error("mmap fails. error = {}", sys::error());
|
||||||
::shm_unlink(name.c_str());
|
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
return new shm_handle{std::move(name), size, mem};
|
return new shm_handle{std::move(name), size, mem};
|
||||||
@ -119,23 +142,16 @@ result<shm_t> shm_open(std::string name, std::size_t size, mode::type type) noex
|
|||||||
*/
|
*/
|
||||||
result_code shm_close(shm_t h) noexcept {
|
result_code shm_close(shm_t h) noexcept {
|
||||||
LIBIMP_LOG_();
|
LIBIMP_LOG_();
|
||||||
if (h == nullptr) {
|
auto shm = valid(h);
|
||||||
log.error("shm handle is null.");
|
if (shm == nullptr) return {};
|
||||||
return {};
|
|
||||||
}
|
|
||||||
auto shm = static_cast<shm_handle *>(h);
|
|
||||||
if (shm->memp == nullptr) {
|
|
||||||
log.error("memory pointer is null.");
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
if (::munmap(shm->memp, shm->f_sz) == posix::failed) {
|
if (::munmap(shm->memp, shm->f_sz) == posix::failed) {
|
||||||
auto ec = sys::error_code();
|
auto err = sys::error();
|
||||||
log.error("munmap fails. error = {}", sys::error(ec));
|
log.error("munmap({}, {}) fails. error = {}", shm->memp, shm->f_sz, err);
|
||||||
return ec;
|
return err.code();
|
||||||
}
|
}
|
||||||
/// @brief no unlink the file.
|
/// @brief no unlink the file.
|
||||||
delete shm;
|
delete shm;
|
||||||
return {true};
|
return {posix::succ};
|
||||||
}
|
}
|
||||||
|
|
||||||
LIBIPC_NAMESPACE_END_
|
LIBIPC_NAMESPACE_END_
|
||||||
|
|||||||
@ -40,7 +40,7 @@ result_code shm_close(shm_t h) noexcept {
|
|||||||
auto shm = static_cast<shm_handle *>(h);
|
auto shm = static_cast<shm_handle *>(h);
|
||||||
mmap_release(shm->h_fmap, shm->memp);
|
mmap_release(shm->h_fmap, shm->memp);
|
||||||
delete shm;
|
delete shm;
|
||||||
return {true};
|
return {0};
|
||||||
}
|
}
|
||||||
|
|
||||||
LIBIPC_NAMESPACE_END_
|
LIBIPC_NAMESPACE_END_
|
||||||
|
|||||||
@ -12,7 +12,7 @@ TEST(result, ok) {
|
|||||||
EXPECT_FALSE(ret.ok());
|
EXPECT_FALSE(ret.ok());
|
||||||
EXPECT_EQ(ret.value(), 0);
|
EXPECT_EQ(ret.value(), 0);
|
||||||
|
|
||||||
ret = {true};
|
ret = {true, 0};
|
||||||
EXPECT_TRUE(ret);
|
EXPECT_TRUE(ret);
|
||||||
EXPECT_TRUE(ret.ok());
|
EXPECT_TRUE(ret.ok());
|
||||||
EXPECT_EQ(ret.value(), 0);
|
EXPECT_EQ(ret.value(), 0);
|
||||||
@ -29,7 +29,7 @@ TEST(result, code) {
|
|||||||
EXPECT_TRUE(ret.ok());
|
EXPECT_TRUE(ret.ok());
|
||||||
EXPECT_EQ(ret.value(), 1234);
|
EXPECT_EQ(ret.value(), 1234);
|
||||||
|
|
||||||
ret = {false};
|
ret = {false, 0};
|
||||||
EXPECT_FALSE(ret);
|
EXPECT_FALSE(ret);
|
||||||
EXPECT_FALSE(ret.ok());
|
EXPECT_FALSE(ret.ok());
|
||||||
EXPECT_EQ(ret.value(), 0);
|
EXPECT_EQ(ret.value(), 0);
|
||||||
@ -62,7 +62,7 @@ TEST(result, fmt) {
|
|||||||
EXPECT_EQ(fmt::format("{}", r1), "[fail, value = 0]");
|
EXPECT_EQ(fmt::format("{}", r1), "[fail, value = 0]");
|
||||||
imp::result_code r2(true, 65537);
|
imp::result_code r2(true, 65537);
|
||||||
EXPECT_EQ(fmt::format("{}", r2), "[succ, value = 65537]");
|
EXPECT_EQ(fmt::format("{}", r2), "[succ, value = 65537]");
|
||||||
imp::result_code r3(true);
|
imp::result_code r3(0);
|
||||||
EXPECT_EQ(fmt::format("{}", r3), "[succ, value = 0]");
|
EXPECT_EQ(fmt::format("{}", r3), "[succ, value = 0]");
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user