From ea2b4fb4935627e4dea48f193eeb0019155a3abe Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Tue, 10 May 2022 09:48:08 +0200 Subject: Use our own implementation of C++14 threads on MinGW --- libbutl/mingw-shared_mutex.hxx | 124 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 124 insertions(+) create mode 100644 libbutl/mingw-shared_mutex.hxx (limited to 'libbutl/mingw-shared_mutex.hxx') diff --git a/libbutl/mingw-shared_mutex.hxx b/libbutl/mingw-shared_mutex.hxx new file mode 100644 index 0000000..aacbaf8 --- /dev/null +++ b/libbutl/mingw-shared_mutex.hxx @@ -0,0 +1,124 @@ +/** +* std::shared_mutex et al implementation for MinGW-w64 +* +* Copyright (c) 2017 by Nathaniel J. McClatchey, Athens OH, United States +* Copyright (c) 2022 the build2 authors +* +* Licensed under the simplified (2-clause) BSD License. +* You should have received a copy of the license along with this +* program. +* +* This code is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +*/ + +#ifndef LIBBUTL_MINGW_SHARED_MUTEX_HXX +#define LIBBUTL_MINGW_SHARED_MUTEX_HXX + +#if !defined(__cplusplus) || (__cplusplus < 201402L) +# error C++14 compiler required +#endif + +#if !defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0601 +# error _WIN32_WINNT should be 0x0601 (Windows 7) or greater +#endif + +#include +// For descriptive errors. +#include +// For timing in shared_timed_mutex. +#include +#include + +#include // shared_lock + +// For defer_lock_t, adopt_lock_t, and try_to_lock_t +#include + +#include + +namespace mingw_stdthread +{ + using std::shared_lock; + + class condition_variable_any; + + // Slim Reader-Writer (SRW)-based implementation that requires Windows 7. + // + class shared_mutex : mutex + { + friend class condition_variable_any; + public: + using mutex::native_handle_type; + using mutex::lock; + using mutex::try_lock; + using mutex::unlock; + using mutex::native_handle; + + void lock_shared () + { + AcquireSRWLockShared(&mHandle); + } + + void unlock_shared () + { + ReleaseSRWLockShared(&mHandle); + } + + bool try_lock_shared () + { + return TryAcquireSRWLockShared(&mHandle) != 0; + } + }; + + class shared_timed_mutex : shared_mutex + { + typedef shared_mutex Base; + public: + using Base::lock; + using Base::try_lock; + using Base::unlock; + using Base::lock_shared; + using Base::try_lock_shared; + using Base::unlock_shared; + + template< class Clock, class Duration > + bool try_lock_until ( const std::chrono::time_point& cutoff ) + { + do + { + if (try_lock()) + return true; + } + while (std::chrono::steady_clock::now() < cutoff); + return false; + } + + template< class Rep, class Period > + bool try_lock_for (const std::chrono::duration& rel_time) + { + return try_lock_until(std::chrono::steady_clock::now() + rel_time); + } + + template< class Clock, class Duration > + bool try_lock_shared_until ( const std::chrono::time_point& cutoff ) + { + do + { + if (try_lock_shared()) + return true; + } + while (std::chrono::steady_clock::now() < cutoff); + return false; + } + + template< class Rep, class Period > + bool try_lock_shared_for (const std::chrono::duration& rel_time) + { + return try_lock_shared_until(std::chrono::steady_clock::now() + rel_time); + } + }; +} + +#endif // LIBBUTL_MINGW_SHARED_MUTEX_HXX -- cgit v1.1