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
267344LIBIPC_NAMESPACE_END_
0 commit comments