Flutter Engine
thread_checker.h
Go to the documentation of this file.
1 // Copyright 2013 The Flutter Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 // A class for checking that the current thread is/isn't the same as an initial
6 // thread.
7 
8 #ifndef FLUTTER_FML_MEMORY_THREAD_CHECKER_H_
9 #define FLUTTER_FML_MEMORY_THREAD_CHECKER_H_
10 
11 #include "flutter/fml/build_config.h"
12 #include "flutter/fml/logging.h"
13 #include "flutter/fml/macros.h"
14 
15 #if defined(OS_WIN)
16 #include <windows.h>
17 #else
18 #include <pthread.h>
19 #endif
20 
21 namespace fml {
22 
23 // A simple class that records the identity of the thread that it was created
24 // on, and at later points can tell if the current thread is the same as its
25 // creation thread. This class is thread-safe.
26 //
27 // Note: Unlike Chromium's |base::ThreadChecker|, this is *not* Debug-only (so
28 // #ifdef it out if you want something Debug-only). (Rationale: Having a
29 // |CalledOnValidThread()| that lies in Release builds seems bad. Moreover,
30 // there's a small space cost to having even an empty class. )
31 class ThreadChecker final {
32  public:
33 #if defined(OS_WIN)
34  ThreadChecker() : self_(GetCurrentThreadId()) {}
35  ~ThreadChecker() {}
36 
37  bool IsCreationThreadCurrent() const { return GetCurrentThreadId() == self_; }
38 
39  private:
40  DWORD self_;
41 
42 #else
43  ThreadChecker() : self_(pthread_self()) {}
45 
46  // Returns true if the current thread is the thread this object was created
47  // on and false otherwise.
48  bool IsCreationThreadCurrent() const {
49  pthread_t current_thread = pthread_self();
50  bool is_creation_thread_current = !!pthread_equal(current_thread, self_);
51 #ifdef __APPLE__
52  // TODO(https://github.com/flutter/flutter/issues/45272): Implement for
53  // other platforms.
54  if (!is_creation_thread_current) {
55  static const int buffer_length = 128;
56  char expected_thread[buffer_length];
57  char actual_thread[buffer_length];
58  if (0 == pthread_getname_np(current_thread, actual_thread,
59  buffer_length) &&
60  0 == pthread_getname_np(self_, actual_thread, buffer_length)) {
61  FML_DLOG(ERROR) << "IsCreationThreadCurrent expected thread: '"
62  << expected_thread << "' actual thread:'"
63  << actual_thread << "'";
64  }
65  }
66 #endif // __APPLE__
67  return is_creation_thread_current;
68  }
69 
70  private:
71  pthread_t self_;
72 #endif
73 };
74 
75 #if !defined(NDEBUG)
76 #define FML_DECLARE_THREAD_CHECKER(c) fml::ThreadChecker c
77 #define FML_DCHECK_CREATION_THREAD_IS_CURRENT(c) \
78  FML_DCHECK((c).IsCreationThreadCurrent())
79 #else
80 #define FML_DECLARE_THREAD_CHECKER(c)
81 #define FML_DCHECK_CREATION_THREAD_IS_CURRENT(c) ((void)0)
82 #endif
83 
84 } // namespace fml
85 
86 #endif // FLUTTER_FML_MEMORY_THREAD_CHECKER_H_
bool IsCreationThreadCurrent() const
Definition: ascii_trie.cc:9
#define FML_DLOG(severity)
Definition: logging.h:85