mirror of
https://github.com/mutouyun/cpp-ipc.git
synced 2025-12-06 16:56:45 +08:00
Refactor default_traits to include support for enum types
This commit is contained in:
parent
1c2fee0d72
commit
f38d77beb9
@ -92,7 +92,8 @@ struct default_traits<void, ___> {
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct default_traits<T, std::enable_if_t<std::is_integral<T>::value>> : generic_traits<T> {
|
||||
struct default_traits<T, std::enable_if_t<std::is_integral<T>::value || std::is_enum<T>::value>>
|
||||
: generic_traits<T> {
|
||||
/// \brief Custom initialization.
|
||||
static constexpr void init_code(typename generic_traits<T>::storage_t &code,
|
||||
T value, bool ok) noexcept {
|
||||
@ -192,7 +193,7 @@ std::string default_traits<void, ___>::format(result<void> const &r) {
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
std::string default_traits<T, std::enable_if_t<std::is_integral<T>::value>>
|
||||
std::string default_traits<T, std::enable_if_t<std::is_integral<T>::value || std::is_enum<T>::value>>
|
||||
::format(result<T> const &r) noexcept {
|
||||
return fmt(*r);
|
||||
}
|
||||
|
||||
@ -14,10 +14,12 @@
|
||||
#include "libimp/log.h"
|
||||
#include "libimp/system.h"
|
||||
#include "libimp/codecvt.h"
|
||||
#include "libimp/span.h"
|
||||
|
||||
#include "libipc/def.h"
|
||||
|
||||
LIBIPC_NAMESPACE_BEG_
|
||||
|
||||
using namespace ::LIBIMP;
|
||||
|
||||
namespace winapi {
|
||||
@ -94,7 +96,7 @@ inline result<void> close_handle(HANDLE h) noexcept {
|
||||
*
|
||||
* \return File mapping object HANDLE, NULL on error.
|
||||
*/
|
||||
result<HANDLE> mmap_open(std::string const &file, std::size_t size, mode::type type) noexcept {
|
||||
inline result<HANDLE> mmap_open(std::string const &file, std::size_t size, mode::type type) noexcept {
|
||||
LIBIMP_LOG_();
|
||||
if (file.empty()) {
|
||||
log.error("file name is empty.");
|
||||
@ -157,7 +159,7 @@ result<HANDLE> mmap_open(std::string const &file, std::size_t size, mode::type t
|
||||
* \brief Maps a view of a file mapping into the address space of a calling process.
|
||||
* \see https://docs.microsoft.com/en-us/windows/win32/api/memoryapi/nf-memoryapi-mapviewoffile
|
||||
*/
|
||||
result<LPVOID> mmap_memof(HANDLE h) {
|
||||
inline result<LPVOID> mmap_memof(HANDLE h) {
|
||||
LIBIMP_LOG_();
|
||||
if (h == NULL) {
|
||||
log.error("handle is null.");
|
||||
@ -176,7 +178,7 @@ result<LPVOID> mmap_memof(HANDLE h) {
|
||||
* \brief Retrieves the size about a range of pages in the virtual address space of the calling process.
|
||||
* \see https://docs.microsoft.com/en-us/windows/win32/api/memoryapi/nf-memoryapi-virtualquery
|
||||
*/
|
||||
result<SIZE_T> mmap_sizeof(LPCVOID mem) {
|
||||
inline result<SIZE_T> mmap_sizeof(LPCVOID mem) {
|
||||
LIBIMP_LOG_();
|
||||
if (mem == NULL) {
|
||||
log.error("memory pointer is null.");
|
||||
@ -195,7 +197,7 @@ result<SIZE_T> mmap_sizeof(LPCVOID mem) {
|
||||
* \brief Unmaps a mapped view of a file from the calling process's address space.
|
||||
* \see https://docs.microsoft.com/en-us/windows/win32/api/memoryapi/nf-memoryapi-unmapviewoffile
|
||||
*/
|
||||
result<void> mmap_release(HANDLE h, LPCVOID mem) {
|
||||
inline result<void> mmap_release(HANDLE h, LPCVOID mem) {
|
||||
LIBIMP_LOG_();
|
||||
if (h == NULL) {
|
||||
log.error("handle is null.");
|
||||
@ -211,5 +213,55 @@ result<void> mmap_release(HANDLE h, LPCVOID mem) {
|
||||
return winapi::close_handle(h);
|
||||
}
|
||||
|
||||
enum class wait_result {
|
||||
object_0,
|
||||
abandoned,
|
||||
timeout
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Waits until the specified object is in the signaled state or the time-out interval elapses.
|
||||
* \see https://learn.microsoft.com/en-us/windows/win32/api/synchapi/nf-synchapi-waitforsingleobject
|
||||
*/
|
||||
inline result<wait_result> wait_for_single_object(HANDLE h, std::int64_t ms) noexcept {
|
||||
LIBIMP_LOG_();
|
||||
DWORD dwMilliseconds = (ms < 0) ? INFINITE : static_cast<DWORD>(ms);
|
||||
DWORD r = ::WaitForSingleObject(h, dwMilliseconds);
|
||||
if (r == WAIT_FAILED) {
|
||||
auto err = sys::error();
|
||||
log.error("failed: WaitForSingleObject(", h, ", ", dwMilliseconds, "). error = ", err);
|
||||
return err;
|
||||
}
|
||||
if (r == WAIT_OBJECT_0) {
|
||||
return wait_result::object_0;
|
||||
}
|
||||
if (r == WAIT_ABANDONED) {
|
||||
return wait_result::abandoned;
|
||||
}
|
||||
return wait_result::timeout;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Waits until one or all of the specified objects are in the signaled state or the time-out interval elapses.
|
||||
* \see https://learn.microsoft.com/en-us/windows/win32/api/synchapi/nf-synchapi-waitformultipleobjects
|
||||
*/
|
||||
inline result<wait_result> wait_for_multiple_objects(span<HANDLE const> handles, std::int64_t ms) noexcept {
|
||||
LIBIMP_LOG_();
|
||||
DWORD dwMilliseconds = (ms < 0) ? INFINITE : static_cast<DWORD>(ms);
|
||||
DWORD r = ::WaitForMultipleObjects(static_cast<DWORD>(handles.size()), handles.data(), FALSE, dwMilliseconds);
|
||||
if (r == WAIT_FAILED) {
|
||||
auto err = sys::error();
|
||||
log.error("failed: WaitForMultipleObjects(", handles.size(), ", ", dwMilliseconds, "). error = ", err);
|
||||
return err;
|
||||
}
|
||||
if ((r >= WAIT_OBJECT_0) && (r < WAIT_OBJECT_0 + handles.size())) {
|
||||
return wait_result::object_0;
|
||||
}
|
||||
if ((r >= WAIT_ABANDONED_0) && (r < WAIT_ABANDONED_0 + handles.size())) {
|
||||
return wait_result::abandoned;
|
||||
}
|
||||
return wait_result::timeout;
|
||||
}
|
||||
|
||||
} // namespace winapi
|
||||
LIBIPC_NAMESPACE_END_
|
||||
|
||||
@ -95,21 +95,18 @@ result<bool> evt_wait(evt_t evt, std::int64_t ms) noexcept {
|
||||
log.error("handle is null.");
|
||||
return std::make_error_code(std::errc::invalid_argument);
|
||||
}
|
||||
DWORD dwMilliseconds = (ms < 0) ? INFINITE : static_cast<DWORD>(ms);
|
||||
auto r = ::WaitForSingleObject(evt->h_event, dwMilliseconds);
|
||||
if (r == WAIT_TIMEOUT) {
|
||||
return false;
|
||||
auto r = winapi::wait_for_single_object(evt->h_event, ms);
|
||||
if (!r) {
|
||||
return r.error();
|
||||
}
|
||||
if (r == WAIT_ABANDONED_0) {
|
||||
log.error("failed: WaitForSingleObject(", evt->h_event, ", ", dwMilliseconds, "). error = WAIT_ABANDONED_0");
|
||||
return {};
|
||||
}
|
||||
if (r == WAIT_OBJECT_0) {
|
||||
if (*r == winapi::wait_result::object_0) {
|
||||
return true;
|
||||
}
|
||||
auto err = sys::error();
|
||||
log.error("failed: WaitForSingleObject(", evt->h_event, ", ", dwMilliseconds, "). error = ", err);
|
||||
return err;
|
||||
if (*r == winapi::wait_result::abandoned) {
|
||||
log.error("failed: WaitForSingleObject(", evt->h_event, ", ", ms, "). error = WAIT_ABANDONED");
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -132,21 +129,18 @@ result<bool> evt_wait(::LIBIMP::span<evt_t const> evts, std::int64_t ms) noexcep
|
||||
handles[i] = evts[i]->h_event;
|
||||
}
|
||||
// Wait for the events.
|
||||
DWORD dwMilliseconds = (ms < 0) ? INFINITE : static_cast<DWORD>(ms);
|
||||
auto r = ::WaitForMultipleObjects(static_cast<DWORD>(handles.size()), handles.data(), FALSE, dwMilliseconds);
|
||||
if (r == WAIT_TIMEOUT) {
|
||||
return false;
|
||||
auto r = winapi::wait_for_multiple_objects(handles, ms);
|
||||
if (!r) {
|
||||
return r.error();
|
||||
}
|
||||
if ((r >= WAIT_ABANDONED_0) && (r < WAIT_ABANDONED_0 + handles.size())) {
|
||||
log.error("failed: WaitForMultipleObjects(", handles.size(), ", ", dwMilliseconds, "). error = WAIT_ABANDONED_0 + ", r - WAIT_ABANDONED_0);
|
||||
return {};
|
||||
}
|
||||
if ((r >= WAIT_OBJECT_0) && (r < WAIT_OBJECT_0 + handles.size())) {
|
||||
if (*r == winapi::wait_result::object_0) {
|
||||
return true;
|
||||
}
|
||||
auto err = sys::error();
|
||||
log.error("failed: WaitForMultipleObjects(", handles.size(), ", ", dwMilliseconds, "). error = ", err);
|
||||
return err;
|
||||
if (*r == winapi::wait_result::abandoned) {
|
||||
log.error("failed: WaitForMultipleObjects(", handles.size(), ", ", ms, "). error = WAIT_ABANDONED");
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
LIBIPC_NAMESPACE_END_
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user