Skip to content

Commit f38d77b

Browse files
committed
Refactor default_traits to include support for enum types
1 parent 1c2fee0 commit f38d77b

File tree

3 files changed

+77
-30
lines changed

3 files changed

+77
-30
lines changed

include/libimp/result.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,8 @@ struct default_traits<void, ___> {
9292
};
9393

9494
template <typename T>
95-
struct default_traits<T, std::enable_if_t<std::is_integral<T>::value>> : generic_traits<T> {
95+
struct default_traits<T, std::enable_if_t<std::is_integral<T>::value || std::is_enum<T>::value>>
96+
: generic_traits<T> {
9697
/// \brief Custom initialization.
9798
static constexpr void init_code(typename generic_traits<T>::storage_t &code,
9899
T value, bool ok) noexcept {
@@ -192,7 +193,7 @@ std::string default_traits<void, ___>::format(result<void> const &r) {
192193
}
193194

194195
template <typename T>
195-
std::string default_traits<T, std::enable_if_t<std::is_integral<T>::value>>
196+
std::string default_traits<T, std::enable_if_t<std::is_integral<T>::value || std::is_enum<T>::value>>
196197
::format(result<T> const &r) noexcept {
197198
return fmt(*r);
198199
}

src/libipc/platform/win/api.h

Lines changed: 56 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,12 @@
1414
#include "libimp/log.h"
1515
#include "libimp/system.h"
1616
#include "libimp/codecvt.h"
17+
#include "libimp/span.h"
1718

1819
#include "libipc/def.h"
1920

2021
LIBIPC_NAMESPACE_BEG_
22+
2123
using namespace ::LIBIMP;
2224

2325
namespace winapi {
@@ -94,7 +96,7 @@ inline result<void> close_handle(HANDLE h) noexcept {
9496
*
9597
* \return File mapping object HANDLE, NULL on error.
9698
*/
97-
result<HANDLE> mmap_open(std::string const &file, std::size_t size, mode::type type) noexcept {
99+
inline result<HANDLE> mmap_open(std::string const &file, std::size_t size, mode::type type) noexcept {
98100
LIBIMP_LOG_();
99101
if (file.empty()) {
100102
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
157159
* \brief Maps a view of a file mapping into the address space of a calling process.
158160
* \see https://docs.microsoft.com/en-us/windows/win32/api/memoryapi/nf-memoryapi-mapviewoffile
159161
*/
160-
result<LPVOID> mmap_memof(HANDLE h) {
162+
inline result<LPVOID> mmap_memof(HANDLE h) {
161163
LIBIMP_LOG_();
162164
if (h == NULL) {
163165
log.error("handle is null.");
@@ -176,7 +178,7 @@ result<LPVOID> mmap_memof(HANDLE h) {
176178
* \brief Retrieves the size about a range of pages in the virtual address space of the calling process.
177179
* \see https://docs.microsoft.com/en-us/windows/win32/api/memoryapi/nf-memoryapi-virtualquery
178180
*/
179-
result<SIZE_T> mmap_sizeof(LPCVOID mem) {
181+
inline result<SIZE_T> mmap_sizeof(LPCVOID mem) {
180182
LIBIMP_LOG_();
181183
if (mem == NULL) {
182184
log.error("memory pointer is null.");
@@ -195,7 +197,7 @@ result<SIZE_T> mmap_sizeof(LPCVOID mem) {
195197
* \brief Unmaps a mapped view of a file from the calling process's address space.
196198
* \see https://docs.microsoft.com/en-us/windows/win32/api/memoryapi/nf-memoryapi-unmapviewoffile
197199
*/
198-
result<void> mmap_release(HANDLE h, LPCVOID mem) {
200+
inline result<void> mmap_release(HANDLE h, LPCVOID mem) {
199201
LIBIMP_LOG_();
200202
if (h == NULL) {
201203
log.error("handle is null.");
@@ -211,5 +213,55 @@ result<void> mmap_release(HANDLE h, LPCVOID mem) {
211213
return winapi::close_handle(h);
212214
}
213215

216+
enum class wait_result {
217+
object_0,
218+
abandoned,
219+
timeout
220+
};
221+
222+
/**
223+
* \brief Waits until the specified object is in the signaled state or the time-out interval elapses.
224+
* \see https://learn.microsoft.com/en-us/windows/win32/api/synchapi/nf-synchapi-waitforsingleobject
225+
*/
226+
inline result<wait_result> wait_for_single_object(HANDLE h, std::int64_t ms) noexcept {
227+
LIBIMP_LOG_();
228+
DWORD dwMilliseconds = (ms < 0) ? INFINITE : static_cast<DWORD>(ms);
229+
DWORD r = ::WaitForSingleObject(h, dwMilliseconds);
230+
if (r == WAIT_FAILED) {
231+
auto err = sys::error();
232+
log.error("failed: WaitForSingleObject(", h, ", ", dwMilliseconds, "). error = ", err);
233+
return err;
234+
}
235+
if (r == WAIT_OBJECT_0) {
236+
return wait_result::object_0;
237+
}
238+
if (r == WAIT_ABANDONED) {
239+
return wait_result::abandoned;
240+
}
241+
return wait_result::timeout;
242+
}
243+
244+
/**
245+
* \brief Waits until one or all of the specified objects are in the signaled state or the time-out interval elapses.
246+
* \see https://learn.microsoft.com/en-us/windows/win32/api/synchapi/nf-synchapi-waitformultipleobjects
247+
*/
248+
inline result<wait_result> wait_for_multiple_objects(span<HANDLE const> handles, std::int64_t ms) noexcept {
249+
LIBIMP_LOG_();
250+
DWORD dwMilliseconds = (ms < 0) ? INFINITE : static_cast<DWORD>(ms);
251+
DWORD r = ::WaitForMultipleObjects(static_cast<DWORD>(handles.size()), handles.data(), FALSE, dwMilliseconds);
252+
if (r == WAIT_FAILED) {
253+
auto err = sys::error();
254+
log.error("failed: WaitForMultipleObjects(", handles.size(), ", ", dwMilliseconds, "). error = ", err);
255+
return err;
256+
}
257+
if ((r >= WAIT_OBJECT_0) && (r < WAIT_OBJECT_0 + handles.size())) {
258+
return wait_result::object_0;
259+
}
260+
if ((r >= WAIT_ABANDONED_0) && (r < WAIT_ABANDONED_0 + handles.size())) {
261+
return wait_result::abandoned;
262+
}
263+
return wait_result::timeout;
264+
}
265+
214266
} // namespace winapi
215267
LIBIPC_NAMESPACE_END_

src/libipc/platform/win/event_impl.h

Lines changed: 18 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -95,21 +95,18 @@ result<bool> evt_wait(evt_t evt, std::int64_t ms) noexcept {
9595
log.error("handle is null.");
9696
return std::make_error_code(std::errc::invalid_argument);
9797
}
98-
DWORD dwMilliseconds = (ms < 0) ? INFINITE : static_cast<DWORD>(ms);
99-
auto r = ::WaitForSingleObject(evt->h_event, dwMilliseconds);
100-
if (r == WAIT_TIMEOUT) {
101-
return false;
102-
}
103-
if (r == WAIT_ABANDONED_0) {
104-
log.error("failed: WaitForSingleObject(", evt->h_event, ", ", dwMilliseconds, "). error = WAIT_ABANDONED_0");
105-
return {};
98+
auto r = winapi::wait_for_single_object(evt->h_event, ms);
99+
if (!r) {
100+
return r.error();
106101
}
107-
if (r == WAIT_OBJECT_0) {
102+
if (*r == winapi::wait_result::object_0) {
108103
return true;
109104
}
110-
auto err = sys::error();
111-
log.error("failed: WaitForSingleObject(", evt->h_event, ", ", dwMilliseconds, "). error = ", err);
112-
return err;
105+
if (*r == winapi::wait_result::abandoned) {
106+
log.error("failed: WaitForSingleObject(", evt->h_event, ", ", ms, "). error = WAIT_ABANDONED");
107+
return false;
108+
}
109+
return false;
113110
}
114111

115112
/**
@@ -132,21 +129,18 @@ result<bool> evt_wait(::LIBIMP::span<evt_t const> evts, std::int64_t ms) noexcep
132129
handles[i] = evts[i]->h_event;
133130
}
134131
// Wait for the events.
135-
DWORD dwMilliseconds = (ms < 0) ? INFINITE : static_cast<DWORD>(ms);
136-
auto r = ::WaitForMultipleObjects(static_cast<DWORD>(handles.size()), handles.data(), FALSE, dwMilliseconds);
137-
if (r == WAIT_TIMEOUT) {
138-
return false;
139-
}
140-
if ((r >= WAIT_ABANDONED_0) && (r < WAIT_ABANDONED_0 + handles.size())) {
141-
log.error("failed: WaitForMultipleObjects(", handles.size(), ", ", dwMilliseconds, "). error = WAIT_ABANDONED_0 + ", r - WAIT_ABANDONED_0);
142-
return {};
132+
auto r = winapi::wait_for_multiple_objects(handles, ms);
133+
if (!r) {
134+
return r.error();
143135
}
144-
if ((r >= WAIT_OBJECT_0) && (r < WAIT_OBJECT_0 + handles.size())) {
136+
if (*r == winapi::wait_result::object_0) {
145137
return true;
146138
}
147-
auto err = sys::error();
148-
log.error("failed: WaitForMultipleObjects(", handles.size(), ", ", dwMilliseconds, "). error = ", err);
149-
return err;
139+
if (*r == winapi::wait_result::abandoned) {
140+
log.error("failed: WaitForMultipleObjects(", handles.size(), ", ", ms, "). error = WAIT_ABANDONED");
141+
return false;
142+
}
143+
return false;
150144
}
151145

152146
LIBIPC_NAMESPACE_END_

0 commit comments

Comments
 (0)