diff options
Diffstat (limited to 'build2/types')
-rw-r--r-- | build2/types | 56 |
1 files changed, 53 insertions, 3 deletions
diff --git a/build2/types b/build2/types index f8abef2..1e7a347 100644 --- a/build2/types +++ b/build2/types @@ -9,7 +9,6 @@ #include <tuple> #include <vector> #include <string> -#include <future> #include <memory> // unique_ptr, shared_ptr #include <utility> // pair, move() #include <cstddef> // size_t, nullptr_t @@ -19,6 +18,11 @@ #include <functional> // function, reference_wrapper #include <initializer_list> +#include <mutex> +#include <future> +#include <butl/ft/shared_mutex> +#include <shared_mutex> + #include <ios> // ios_base::failure #include <exception> // exception #include <stdexcept> // logic_error, invalid_argument, runtime_error @@ -69,10 +73,56 @@ namespace build2 using std::istream; using std::ostream; + // Concurrency. + // using std::future; - // Exceptions. While <exception> is included, there is no using for - // std::exception -- use qualified. +#ifdef __cpp_lib_shared_mutex + using shared_mutex = std::shared_mutex; +#else + using shared_mutex = std::shared_timed_mutex; +#endif + + using slock = std::shared_lock<shared_mutex>; + using ulock = std::unique_lock<shared_mutex>; + + // Re-lock shared to exclusive for the lifetime or rlock. + // + struct rlock + { + explicit + rlock (slock* sl) + : sl_ (sl) + { + if (sl_ != nullptr) + { + sl_->unlock (); + ul_ = ulock (*sl_->mutex ()); + } + } + + ~rlock () + { + if (sl_ != nullptr) + { + ul_.unlock (); + sl_->lock (); + } + } + + // Can be treated as const ulock. + // + operator const ulock& () const {return ul_;} + + private: + slock* sl_; + ulock ul_; + }; + + // Exceptions. + // + // While <exception> is included, there is no using for std::exception -- + // use qualified. // using std::logic_error; using std::invalid_argument; |