1d3a28867527364fda9e3782be281de481e97a37dhenrik.lundin@webrtc.org/*
2d3a28867527364fda9e3782be281de481e97a37dhenrik.lundin@webrtc.org *  Copyright (c) 2014 The WebRTC project authors. All Rights Reserved.
3d3a28867527364fda9e3782be281de481e97a37dhenrik.lundin@webrtc.org *
4d3a28867527364fda9e3782be281de481e97a37dhenrik.lundin@webrtc.org *  Use of this source code is governed by a BSD-style license
5d3a28867527364fda9e3782be281de481e97a37dhenrik.lundin@webrtc.org *  that can be found in the LICENSE file in the root of the source
6d3a28867527364fda9e3782be281de481e97a37dhenrik.lundin@webrtc.org *  tree. An additional intellectual property rights grant can be found
7d3a28867527364fda9e3782be281de481e97a37dhenrik.lundin@webrtc.org *  in the file PATENTS.  All contributing project authors may
8d3a28867527364fda9e3782be281de481e97a37dhenrik.lundin@webrtc.org *  be found in the AUTHORS file in the root of the source tree.
9d3a28867527364fda9e3782be281de481e97a37dhenrik.lundin@webrtc.org */
10d3a28867527364fda9e3782be281de481e97a37dhenrik.lundin@webrtc.org
11d3a28867527364fda9e3782be281de481e97a37dhenrik.lundin@webrtc.org// Borrowed from Chromium's src/base/threading/thread_checker.h.
12d3a28867527364fda9e3782be281de481e97a37dhenrik.lundin@webrtc.org
13d3a28867527364fda9e3782be281de481e97a37dhenrik.lundin@webrtc.org#ifndef WEBRTC_BASE_THREAD_CHECKER_H_
14d3a28867527364fda9e3782be281de481e97a37dhenrik.lundin@webrtc.org#define WEBRTC_BASE_THREAD_CHECKER_H_
15d3a28867527364fda9e3782be281de481e97a37dhenrik.lundin@webrtc.org
16d3a28867527364fda9e3782be281de481e97a37dhenrik.lundin@webrtc.org// Apart from debug builds, we also enable the thread checker in
17d3a28867527364fda9e3782be281de481e97a37dhenrik.lundin@webrtc.org// builds with DCHECK_ALWAYS_ON so that trybots and waterfall bots
18d3a28867527364fda9e3782be281de481e97a37dhenrik.lundin@webrtc.org// with this define will get the same level of thread checking as
19d3a28867527364fda9e3782be281de481e97a37dhenrik.lundin@webrtc.org// debug bots.
20d3a28867527364fda9e3782be281de481e97a37dhenrik.lundin@webrtc.org//
21d3a28867527364fda9e3782be281de481e97a37dhenrik.lundin@webrtc.org// Note that this does not perfectly match situations where DCHECK is
22d3a28867527364fda9e3782be281de481e97a37dhenrik.lundin@webrtc.org// enabled.  For example a non-official release build may have
23d3a28867527364fda9e3782be281de481e97a37dhenrik.lundin@webrtc.org// DCHECK_ALWAYS_ON undefined (and therefore ThreadChecker would be
24d3a28867527364fda9e3782be281de481e97a37dhenrik.lundin@webrtc.org// disabled) but have DCHECKs enabled at runtime.
25d3a28867527364fda9e3782be281de481e97a37dhenrik.lundin@webrtc.org#if (!defined(NDEBUG) || defined(DCHECK_ALWAYS_ON))
26d3a28867527364fda9e3782be281de481e97a37dhenrik.lundin@webrtc.org#define ENABLE_THREAD_CHECKER 1
27d3a28867527364fda9e3782be281de481e97a37dhenrik.lundin@webrtc.org#else
28d3a28867527364fda9e3782be281de481e97a37dhenrik.lundin@webrtc.org#define ENABLE_THREAD_CHECKER 0
29d3a28867527364fda9e3782be281de481e97a37dhenrik.lundin@webrtc.org#endif
30d3a28867527364fda9e3782be281de481e97a37dhenrik.lundin@webrtc.org
31d3a28867527364fda9e3782be281de481e97a37dhenrik.lundin@webrtc.org#include "webrtc/base/thread_checker_impl.h"
32d3a28867527364fda9e3782be281de481e97a37dhenrik.lundin@webrtc.org
33d3a28867527364fda9e3782be281de481e97a37dhenrik.lundin@webrtc.orgnamespace rtc {
34d3a28867527364fda9e3782be281de481e97a37dhenrik.lundin@webrtc.org
35d3a28867527364fda9e3782be281de481e97a37dhenrik.lundin@webrtc.org// Do nothing implementation, for use in release mode.
36d3a28867527364fda9e3782be281de481e97a37dhenrik.lundin@webrtc.org//
37d3a28867527364fda9e3782be281de481e97a37dhenrik.lundin@webrtc.org// Note: You should almost always use the ThreadChecker class to get the
38d3a28867527364fda9e3782be281de481e97a37dhenrik.lundin@webrtc.org// right version for your build configuration.
39d3a28867527364fda9e3782be281de481e97a37dhenrik.lundin@webrtc.orgclass ThreadCheckerDoNothing {
40d3a28867527364fda9e3782be281de481e97a37dhenrik.lundin@webrtc.org public:
41d3a28867527364fda9e3782be281de481e97a37dhenrik.lundin@webrtc.org  bool CalledOnValidThread() const {
42d3a28867527364fda9e3782be281de481e97a37dhenrik.lundin@webrtc.org    return true;
43d3a28867527364fda9e3782be281de481e97a37dhenrik.lundin@webrtc.org  }
44d3a28867527364fda9e3782be281de481e97a37dhenrik.lundin@webrtc.org
45d3a28867527364fda9e3782be281de481e97a37dhenrik.lundin@webrtc.org  void DetachFromThread() {}
46d3a28867527364fda9e3782be281de481e97a37dhenrik.lundin@webrtc.org};
47d3a28867527364fda9e3782be281de481e97a37dhenrik.lundin@webrtc.org
48d3a28867527364fda9e3782be281de481e97a37dhenrik.lundin@webrtc.org// ThreadChecker is a helper class used to help verify that some methods of a
49d3a28867527364fda9e3782be281de481e97a37dhenrik.lundin@webrtc.org// class are called from the same thread. It provides identical functionality to
50d3a28867527364fda9e3782be281de481e97a37dhenrik.lundin@webrtc.org// base::NonThreadSafe, but it is meant to be held as a member variable, rather
51d3a28867527364fda9e3782be281de481e97a37dhenrik.lundin@webrtc.org// than inherited from base::NonThreadSafe.
52d3a28867527364fda9e3782be281de481e97a37dhenrik.lundin@webrtc.org//
53d3a28867527364fda9e3782be281de481e97a37dhenrik.lundin@webrtc.org// While inheriting from base::NonThreadSafe may give a clear indication about
54d3a28867527364fda9e3782be281de481e97a37dhenrik.lundin@webrtc.org// the thread-safety of a class, it may also lead to violations of the style
55d3a28867527364fda9e3782be281de481e97a37dhenrik.lundin@webrtc.org// guide with regard to multiple inheritance. The choice between having a
56d3a28867527364fda9e3782be281de481e97a37dhenrik.lundin@webrtc.org// ThreadChecker member and inheriting from base::NonThreadSafe should be based
57d3a28867527364fda9e3782be281de481e97a37dhenrik.lundin@webrtc.org// on whether:
58d3a28867527364fda9e3782be281de481e97a37dhenrik.lundin@webrtc.org//  - Derived classes need to know the thread they belong to, as opposed to
59d3a28867527364fda9e3782be281de481e97a37dhenrik.lundin@webrtc.org//    having that functionality fully encapsulated in the base class.
60d3a28867527364fda9e3782be281de481e97a37dhenrik.lundin@webrtc.org//  - Derived classes should be able to reassign the base class to another
61d3a28867527364fda9e3782be281de481e97a37dhenrik.lundin@webrtc.org//    thread, via DetachFromThread.
62d3a28867527364fda9e3782be281de481e97a37dhenrik.lundin@webrtc.org//
63d3a28867527364fda9e3782be281de481e97a37dhenrik.lundin@webrtc.org// If neither of these are true, then having a ThreadChecker member and calling
64d3a28867527364fda9e3782be281de481e97a37dhenrik.lundin@webrtc.org// CalledOnValidThread is the preferable solution.
65d3a28867527364fda9e3782be281de481e97a37dhenrik.lundin@webrtc.org//
66d3a28867527364fda9e3782be281de481e97a37dhenrik.lundin@webrtc.org// Example:
67d3a28867527364fda9e3782be281de481e97a37dhenrik.lundin@webrtc.org// class MyClass {
68d3a28867527364fda9e3782be281de481e97a37dhenrik.lundin@webrtc.org//  public:
69d3a28867527364fda9e3782be281de481e97a37dhenrik.lundin@webrtc.org//   void Foo() {
70d3a28867527364fda9e3782be281de481e97a37dhenrik.lundin@webrtc.org//     DCHECK(thread_checker_.CalledOnValidThread());
71d3a28867527364fda9e3782be281de481e97a37dhenrik.lundin@webrtc.org//     ... (do stuff) ...
72d3a28867527364fda9e3782be281de481e97a37dhenrik.lundin@webrtc.org//   }
73d3a28867527364fda9e3782be281de481e97a37dhenrik.lundin@webrtc.org//
74d3a28867527364fda9e3782be281de481e97a37dhenrik.lundin@webrtc.org//  private:
75d3a28867527364fda9e3782be281de481e97a37dhenrik.lundin@webrtc.org//   ThreadChecker thread_checker_;
76d3a28867527364fda9e3782be281de481e97a37dhenrik.lundin@webrtc.org// }
77d3a28867527364fda9e3782be281de481e97a37dhenrik.lundin@webrtc.org//
78d3a28867527364fda9e3782be281de481e97a37dhenrik.lundin@webrtc.org// In Release mode, CalledOnValidThread will always return true.
79d3a28867527364fda9e3782be281de481e97a37dhenrik.lundin@webrtc.org#if ENABLE_THREAD_CHECKER
80d3a28867527364fda9e3782be281de481e97a37dhenrik.lundin@webrtc.orgclass ThreadChecker : public ThreadCheckerImpl {
81d3a28867527364fda9e3782be281de481e97a37dhenrik.lundin@webrtc.org};
82d3a28867527364fda9e3782be281de481e97a37dhenrik.lundin@webrtc.org#else
83d3a28867527364fda9e3782be281de481e97a37dhenrik.lundin@webrtc.orgclass ThreadChecker : public ThreadCheckerDoNothing {
84d3a28867527364fda9e3782be281de481e97a37dhenrik.lundin@webrtc.org};
85d3a28867527364fda9e3782be281de481e97a37dhenrik.lundin@webrtc.org#endif  // ENABLE_THREAD_CHECKER
86d3a28867527364fda9e3782be281de481e97a37dhenrik.lundin@webrtc.org
87d3a28867527364fda9e3782be281de481e97a37dhenrik.lundin@webrtc.org#undef ENABLE_THREAD_CHECKER
88d3a28867527364fda9e3782be281de481e97a37dhenrik.lundin@webrtc.org
89d3a28867527364fda9e3782be281de481e97a37dhenrik.lundin@webrtc.org}  // namespace rtc
90d3a28867527364fda9e3782be281de481e97a37dhenrik.lundin@webrtc.org
91d3a28867527364fda9e3782be281de481e97a37dhenrik.lundin@webrtc.org#endif  // WEBRTC_BASE_THREAD_CHECKER_H_
92