Skip to content

Commit 5eafc13

Browse files
committed
Refactor the windows api adaptation layer
1 parent 7491a33 commit 5eafc13

File tree

4 files changed

+96
-76
lines changed

4 files changed

+96
-76
lines changed

src/libipc/platform/win/api.h

+85-8
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include "libimp/system.h"
1616
#include "libimp/codecvt.h"
1717
#include "libimp/span.h"
18+
#include "libimp/detect_plat.h"
1819

1920
#include "libipc/def.h"
2021

@@ -33,10 +34,10 @@ inline tstring to_tstring(std::string const &str) {
3334
}
3435

3536
/**
36-
* \brief Create a SECURITY_ATTRIBUTES structure singleton
37+
* \brief Creates or opens a SECURITY_ATTRIBUTES structure singleton
3738
* \see https://docs.microsoft.com/en-us/previous-versions/windows/desktop/legacy/aa379560(v=vs.85)
3839
*/
39-
inline LPSECURITY_ATTRIBUTES get_sa() {
40+
inline LPSECURITY_ATTRIBUTES get_security_descriptor() {
4041
static struct initiator {
4142

4243
SECURITY_DESCRIPTOR sd_;
@@ -46,7 +47,7 @@ inline LPSECURITY_ATTRIBUTES get_sa() {
4647

4748
initiator() {
4849
using namespace ::LIBIMP;
49-
LIBIMP_LOG_("get_sa");
50+
LIBIMP_LOG_("get_security_descriptor");
5051
if (!::InitializeSecurityDescriptor(&sd_, SECURITY_DESCRIPTOR_REVISION)) {
5152
log.error("failed: InitializeSecurityDescriptor(SECURITY_DESCRIPTOR_REVISION). "
5253
"error = ", sys::error());
@@ -96,7 +97,7 @@ inline result<void> close_handle(HANDLE h) noexcept {
9697
*
9798
* \return File mapping object HANDLE, NULL on error.
9899
*/
99-
inline result<HANDLE> mmap_open(std::string const &file, std::size_t size, mode::type type) noexcept {
100+
inline result<HANDLE> open_file_mapping(std::string const &file, std::size_t size, mode::type type) noexcept {
100101
LIBIMP_LOG_();
101102
if (file.empty()) {
102103
log.error("file name is empty.");
@@ -121,7 +122,7 @@ inline result<HANDLE> mmap_open(std::string const &file, std::size_t size, mode:
121122

122123
// Creates or opens a named or unnamed file mapping object for a specified file.
123124
auto try_create = [&]() -> result<HANDLE> {
124-
HANDLE h = ::CreateFileMapping(INVALID_HANDLE_VALUE, winapi::get_sa(), PAGE_READWRITE | SEC_COMMIT,
125+
HANDLE h = ::CreateFileMapping(INVALID_HANDLE_VALUE, winapi::get_security_descriptor(), PAGE_READWRITE | SEC_COMMIT,
125126
/// \remark dwMaximumSizeHigh always 0 here.
126127
0, static_cast<DWORD>(size), t_name.c_str());
127128
if (h == NULL) {
@@ -159,7 +160,7 @@ inline result<HANDLE> mmap_open(std::string const &file, std::size_t size, mode:
159160
* \brief Maps a view of a file mapping into the address space of a calling process.
160161
* \see https://docs.microsoft.com/en-us/windows/win32/api/memoryapi/nf-memoryapi-mapviewoffile
161162
*/
162-
inline result<LPVOID> mmap_memof(HANDLE h) {
163+
inline result<LPVOID> address_of_file_mapping(HANDLE h) {
163164
LIBIMP_LOG_();
164165
if (h == NULL) {
165166
log.error("handle is null.");
@@ -178,7 +179,7 @@ inline result<LPVOID> mmap_memof(HANDLE h) {
178179
* \brief Retrieves the size about a range of pages in the virtual address space of the calling process.
179180
* \see https://docs.microsoft.com/en-us/windows/win32/api/memoryapi/nf-memoryapi-virtualquery
180181
*/
181-
inline result<SIZE_T> mmap_sizeof(LPCVOID mem) {
182+
inline result<SIZE_T> region_size_of_address(LPCVOID mem) {
182183
LIBIMP_LOG_();
183184
if (mem == NULL) {
184185
log.error("memory pointer is null.");
@@ -197,7 +198,7 @@ inline result<SIZE_T> mmap_sizeof(LPCVOID mem) {
197198
* \brief Unmaps a mapped view of a file from the calling process's address space.
198199
* \see https://docs.microsoft.com/en-us/windows/win32/api/memoryapi/nf-memoryapi-unmapviewoffile
199200
*/
200-
inline result<void> mmap_release(HANDLE h, LPCVOID mem) {
201+
inline result<void> close_file_mapping(HANDLE h, LPCVOID mem) {
201202
LIBIMP_LOG_();
202203
if (h == NULL) {
203204
log.error("handle is null.");
@@ -219,6 +220,8 @@ enum class wait_result {
219220
timeout
220221
};
221222

223+
LIBIMP_INLINE_CONSTEXPR std::int64_t const infinite_time = -1;
224+
222225
/**
223226
* \brief Waits until the specified object is in the signaled state or the time-out interval elapses.
224227
* \see https://learn.microsoft.com/en-us/windows/win32/api/synchapi/nf-synchapi-waitforsingleobject
@@ -263,5 +266,79 @@ inline result<wait_result> wait_for_multiple_objects(span<HANDLE const> handles,
263266
return wait_result::timeout;
264267
}
265268

269+
/**
270+
* \brief Retrieves the current value of the performance counter,
271+
* which is a high resolution (<1us) time stamp that can be used for time-interval measurements.
272+
* \see https://learn.microsoft.com/en-us/windows/win32/api/profileapi/nf-profileapi-queryperformancecounter
273+
*/
274+
inline result<std::int64_t> query_performance_counter() noexcept {
275+
LIBIMP_LOG_();
276+
std::int64_t pc;
277+
BOOL r = ::QueryPerformanceCounter(reinterpret_cast<LARGE_INTEGER *>(&pc));
278+
if (!r) {
279+
auto err = sys::error();
280+
log.error("failed: QueryPerformanceCounter(). error = ", err);
281+
return err;
282+
}
283+
return pc;
284+
}
285+
286+
/**
287+
* \brief Creates or opens a named or unnamed mutex object.
288+
* \see https://learn.microsoft.com/en-us/windows/win32/api/synchapi/nf-synchapi-createmutexa
289+
* \return Mutex object HANDLE, NULL on error.
290+
*/
291+
inline result<HANDLE> open_mutex(char const *name, bool initial_owner) noexcept {
292+
LIBIMP_LOG_();
293+
HANDLE h = ::CreateMutexA(winapi::get_security_descriptor(), initial_owner, name);
294+
if (h == NULL) {
295+
auto err = sys::error();
296+
log.error("failed: CreateMutexA(", initial_owner, ", ", name, "). error = ", err);
297+
return err;
298+
}
299+
return h;
300+
}
301+
302+
/**
303+
* \brief Releases ownership of the specified mutex object.
304+
* \see https://docs.microsoft.com/en-us/windows/win32/api/synchapi/nf-synchapi-releasemutex
305+
*/
306+
inline result<bool> release_mutex(HANDLE h) noexcept {
307+
LIBIMP_LOG_();
308+
if (::ReleaseMutex(h)) {
309+
return true;
310+
}
311+
auto err = sys::error();
312+
log.error("failed: ReleaseMutex. error = ", err);
313+
return err;
314+
}
315+
316+
/**
317+
* \brief Locks the mutex, blocks if the mutex is not available.
318+
* \see https://docs.microsoft.com/en-us/windows/win32/api/synchapi/nf-synchapi-waitforsingleobject
319+
*/
320+
inline result<bool> wait_mutex(HANDLE h, std::int64_t ms) noexcept {
321+
LIBIMP_LOG_();
322+
// If the mutex is abandoned, we need to release it and try again.
323+
for (;;) {
324+
auto r = winapi::wait_for_single_object(h, ms);
325+
if (!r) {
326+
return r.error();
327+
}
328+
if (*r == winapi::wait_result::object_0) {
329+
return true;
330+
}
331+
if (*r == winapi::wait_result::abandoned) {
332+
log.info("failed: WaitForSingleObject(", ms, "). The mutex is abandoned, try again.");
333+
auto rr = release_mutex(h);
334+
if (rr) {
335+
continue;
336+
}
337+
return rr.error();
338+
}
339+
return false;
340+
}
341+
}
342+
266343
} // namespace winapi
267344
LIBIPC_NAMESPACE_END_

src/libipc/platform/win/event_impl.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ bool is_valid(evt_t evt) noexcept {
4242
result<evt_t> evt_open(std::string name) noexcept {
4343
LIBIMP_LOG_();
4444
auto t_name = winapi::to_tstring(name);
45-
auto h = ::CreateEvent(winapi::get_sa(),
45+
auto h = ::CreateEvent(winapi::get_security_descriptor(),
4646
/*bManualReset*/ FALSE,
4747
/*bInitialState*/FALSE,
4848
/*lpName*/ t_name.c_str());

src/libipc/platform/win/mutex_impl.h

+3-60
Original file line numberDiff line numberDiff line change
@@ -6,78 +6,21 @@
66

77
#include "libimp/log.h"
88
#include "libimp/system.h"
9+
#include "libpmr/new.h"
910
#include "libipc/mutex.h"
1011

1112
#include "api.h"
13+
#include "sync_id.h"
1214

1315
LIBIPC_NAMESPACE_BEG_
1416

1517
using namespace ::LIBIMP;
18+
using namespace ::LIBPMR;
1619

1720
struct mutex_handle {
1821

1922
};
2023

21-
namespace winapi {
22-
23-
/**
24-
* \brief Creates or opens a named or unnamed mutex object.
25-
* \see https://learn.microsoft.com/en-us/windows/win32/api/synchapi/nf-synchapi-createmutexa
26-
* \return Mutex object HANDLE, NULL on error.
27-
*/
28-
result<HANDLE> mutex_open_or_create(char const *name, bool initial_owner) noexcept {
29-
LIBIMP_LOG_();
30-
HANDLE h = ::CreateMutexA(winapi::get_sa(), initial_owner, name);
31-
if (h == NULL) {
32-
auto err = sys::error();
33-
log.error("failed: CreateMutexA(", initial_owner, ", ", name, "). error = ", err);
34-
return err;
35-
}
36-
return h;
37-
}
38-
39-
/**
40-
* \brief Releases ownership of the specified mutex object.
41-
* \see https://docs.microsoft.com/en-us/windows/win32/api/synchapi/nf-synchapi-releasemutex
42-
*/
43-
result<bool> mutex_release(HANDLE h) noexcept {
44-
LIBIMP_LOG_();
45-
if (::ReleaseMutex(h)) {
46-
return true;
47-
}
48-
auto err = sys::error();
49-
log.error("failed: ReleaseMutex. error = ", err);
50-
return err;
51-
}
52-
53-
/**
54-
* \brief Locks the mutex, blocks if the mutex is not available.
55-
* \see https://docs.microsoft.com/en-us/windows/win32/api/synchapi/nf-synchapi-waitforsingleobject
56-
*/
57-
result<bool> mutex_wait(HANDLE h, std::int64_t ms) noexcept {
58-
LIBIMP_LOG_();
59-
for (;;) {
60-
auto r = winapi::wait_for_single_object(h, ms);
61-
if (!r) {
62-
return r.error();
63-
}
64-
if (*r == winapi::wait_result::object_0) {
65-
return true;
66-
}
67-
if (*r == winapi::wait_result::abandoned) {
68-
log.info("failed: WaitForSingleObject(", ms, "). The mutex is abandoned, try again.");
69-
auto rr = mutex_release(h);
70-
if (rr) {
71-
continue;
72-
}
73-
return rr.error();
74-
}
75-
return false;
76-
}
77-
}
78-
79-
} // namespace winapi
80-
8124
result<mutex_t> mutex_open(span<::LIBIMP::byte> mem) noexcept {
8225
return {};
8326
}

src/libipc/platform/win/shm_impl.h

+7-7
Original file line numberDiff line numberDiff line change
@@ -28,20 +28,20 @@ struct shm_handle {
2828

2929
result<shm_t> shm_open(std::string name, std::size_t size, mode::type type) noexcept {
3030
LIBIMP_LOG_();
31-
auto h = winapi::mmap_open(name, size, type);
31+
auto h = winapi::open_file_mapping(name, size, type);
3232
if (*h == NULL) {
33-
log.error("failed: mmap_open(name = ", name, ", size = ", size, ", type = ", type, ").");
33+
log.error("failed: OpenFileMapping(name = ", name, ", size = ", size, ", type = ", type, ").");
3434
return h.error();
3535
}
36-
auto mem = winapi::mmap_memof(*h);
36+
auto mem = winapi::address_of_file_mapping(*h);
3737
if (*mem == NULL) {
38-
log.error("failed: mmap_memof(", *h, ").");
38+
log.error("failed: MapViewOfFile(", *h, ").");
3939
winapi::close_handle(*h);
4040
return mem.error();
4141
}
42-
auto sz = winapi::mmap_sizeof(*mem);
42+
auto sz = winapi::region_size_of_address(*mem);
4343
if (!sz) {
44-
log.error("failed: mmap_sizeof(", *mem, ").");
44+
log.error("failed: RegionSizeOfMemory(", *mem, ").");
4545
winapi::close_handle(*h);
4646
return sz.error();
4747
}
@@ -55,7 +55,7 @@ result<void> shm_close(shm_t h) noexcept {
5555
return std::make_error_code(std::errc::invalid_argument);
5656
}
5757
auto shm = static_cast<shm_handle *>(h);
58-
auto ret = winapi::mmap_release(shm->h_fmap, shm->memp);
58+
auto ret = winapi::close_file_mapping(shm->h_fmap, shm->memp);
5959
$delete(shm);
6060
return ret;
6161
}

0 commit comments

Comments
 (0)