aboutsummaryrefslogtreecommitdiff
path: root/android-emu/android/base/fit/ThreadChecker.h
diff options
context:
space:
mode:
Diffstat (limited to 'android-emu/android/base/fit/ThreadChecker.h')
-rw-r--r--android-emu/android/base/fit/ThreadChecker.h87
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