diff options
Diffstat (limited to 'android-emu/android/base/fit/ThreadChecker.h')
-rw-r--r-- | android-emu/android/base/fit/ThreadChecker.h | 87 |
1 files changed, 87 insertions, 0 deletions
diff --git a/android-emu/android/base/fit/ThreadChecker.h b/android-emu/android/base/fit/ThreadChecker.h new file mode 100644 index 00000000..3859ecf1 --- /dev/null +++ b/android-emu/android/base/fit/ThreadChecker.h @@ -0,0 +1,87 @@ +// Copyright 2021 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Copyright 2016 The Fuchsia Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// A class for checking that the current thread is/isn't the same as an initial +// thread. + +#pragma once + +#include <assert.h> + +#include <thread> + +#include "ThreadSafety.h" + +namespace android::base { +namespace fit { + +// A simple class that records the identity of the thread that it was created +// on, and at later points can tell if the current thread is the same as its +// creation thread. This class is thread-safe. +// +// In addition to providing an explicit check of the current thread, +// |thread_checker| complies with BasicLockable, checking the current thread +// when |lock| is called. This allows static thread safety analysis to be used +// to ensure that resources are accessed in a context that is checked (at debug +// runtime) to ensure that it's running on the correct thread: +// +// class MyClass { +// public: +// void Foo() { +// std::lock_guard<fit::thread_checker> locker(thread_checker_); +// resource_ = 0; +// } +// private: +// fit::thread_checker thread_checker_; +// int resource_ GUARDED_BY(thread_checker_); +// } +// +// Note: |lock| checks the thread in debug builds only. +// +class CAPABILITY("mutex") ThreadChecker final { +public: + // Default constructor. Constructs a thread checker bound to the currently + // running thread. + ThreadChecker() : self_(std::this_thread::get_id()) {} + // Constructs a thread checker bound to an explicit other thread. + explicit ThreadChecker(std::thread::id self) : self_(self) {} + ~ThreadChecker() = default; + + // Returns true if the current thread is the thread this object was created + // on and false otherwise. + bool isThreadValid() const { return std::this_thread::get_id() == self_; } + + // Implementation of the BaseLockable requirement + void lock() ACQUIRE() { assert(isThreadValid()); } + + void unlock() RELEASE() {} + +private: + const std::thread::id self_; +}; + +#ifndef NDEBUG +#define DECLARE_THREAD_CHECKER(c) android::base::fit::ThreadChecker c +#define DCHECK_IS_THREAD_VALID(c) assert((c).isThreadValid()) +#else +#define DECLARE_THREAD_CHECKER(c) +#define DCHECK_IS_THREAD_VALID(c) ((void)0) +#endif + +} // namespace fit +} // namespace android::base |