|  | //===----------------------------------------------------------------------===// | 
|  | // | 
|  | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | 
|  | // See https://llvm.org/LICENSE.txt for license information. | 
|  | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | 
|  | // | 
|  | //===----------------------------------------------------------------------===// | 
|  |  | 
|  | #ifndef TEST_SUPPORT_CHECKING_MUTEX_H | 
|  | #define TEST_SUPPORT_CHECKING_MUTEX_H | 
|  |  | 
|  | #include <cassert> | 
|  | #include <chrono> | 
|  |  | 
|  | struct checking_mutex { | 
|  | enum state { | 
|  | locked_via_lock, | 
|  | locked_via_try_lock, | 
|  | locked_via_try_lock_for, | 
|  | locked_via_try_lock_until, | 
|  | unlocked, | 
|  | none, | 
|  | }; | 
|  |  | 
|  | state current_state = unlocked; | 
|  | state last_try      = none; | 
|  | bool reject         = false; | 
|  |  | 
|  | checking_mutex()                      = default; | 
|  | checking_mutex(const checking_mutex&) = delete; | 
|  | ~checking_mutex() { assert(current_state == unlocked); } | 
|  |  | 
|  | void lock() { | 
|  | assert(current_state == unlocked); | 
|  | assert(!reject); | 
|  | current_state = locked_via_lock; | 
|  | last_try      = locked_via_lock; | 
|  | reject        = true; | 
|  | } | 
|  |  | 
|  | void unlock() { | 
|  | assert(current_state != unlocked && current_state != none); | 
|  | last_try      = unlocked; | 
|  | current_state = unlocked; | 
|  | reject        = false; | 
|  | } | 
|  |  | 
|  | bool try_lock() { | 
|  | last_try = locked_via_try_lock; | 
|  | if (reject) | 
|  | return false; | 
|  | current_state = locked_via_try_lock; | 
|  | return true; | 
|  | } | 
|  |  | 
|  | template <class Rep, class Period> | 
|  | bool try_lock_for(const std::chrono::duration<Rep, Period>&) { | 
|  | last_try = locked_via_try_lock_for; | 
|  | if (reject) | 
|  | return false; | 
|  | current_state = locked_via_try_lock_for; | 
|  | return true; | 
|  | } | 
|  |  | 
|  | template <class Clock, class Duration> | 
|  | bool try_lock_until(const std::chrono::time_point<Clock, Duration>&) { | 
|  | last_try = locked_via_try_lock_until; | 
|  | if (reject) | 
|  | return false; | 
|  | current_state = locked_via_try_lock_until; | 
|  | return true; | 
|  | } | 
|  |  | 
|  | checking_mutex* operator&() = delete; | 
|  |  | 
|  | template <class T> | 
|  | void operator,(const T&) = delete; | 
|  | }; | 
|  |  | 
|  | #endif // TEST_SUPPORT_CHECKING_MUTEX_H |