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
2021LIBIPC_NAMESPACE_BEG_
22+
2123using namespace ::LIBIMP;
2224
2325namespace 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
215267LIBIPC_NAMESPACE_END_
0 commit comments