LCOV - code coverage report
Current view: top level - media/webrtc/trunk/webrtc/base - thread_checker.h (source / functions) Hit Total Coverage
Test: output.info Lines: 0 8 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 7 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  *  Copyright (c) 2014 The WebRTC project authors. All Rights Reserved.
       3             :  *
       4             :  *  Use of this source code is governed by a BSD-style license
       5             :  *  that can be found in the LICENSE file in the root of the source
       6             :  *  tree. An additional intellectual property rights grant can be found
       7             :  *  in the file PATENTS.  All contributing project authors may
       8             :  *  be found in the AUTHORS file in the root of the source tree.
       9             :  */
      10             : 
      11             : // Borrowed from Chromium's src/base/threading/thread_checker.h.
      12             : 
      13             : #ifndef WEBRTC_BASE_THREAD_CHECKER_H_
      14             : #define WEBRTC_BASE_THREAD_CHECKER_H_
      15             : 
      16             : // Apart from debug builds, we also enable the thread checker in
      17             : // builds with RTC_DCHECK_IS_ON so that trybots and waterfall bots
      18             : // with this define will get the same level of thread checking as
      19             : // debug bots.
      20             : #define ENABLE_THREAD_CHECKER RTC_DCHECK_IS_ON
      21             : 
      22             : #include "webrtc/base/checks.h"
      23             : #include "webrtc/base/constructormagic.h"
      24             : #include "webrtc/base/thread_annotations.h"
      25             : #include "webrtc/base/thread_checker_impl.h"
      26             : 
      27             : namespace rtc {
      28             : 
      29             : // Do nothing implementation, for use in release mode.
      30             : //
      31             : // Note: You should almost always use the ThreadChecker class to get the
      32             : // right version for your build configuration.
      33             : class ThreadCheckerDoNothing {
      34             :  public:
      35             :   bool CalledOnValidThread() const {
      36             :     return true;
      37             :   }
      38             : 
      39             :   void DetachFromThread() {}
      40             : };
      41             : 
      42             : // ThreadChecker is a helper class used to help verify that some methods of a
      43             : // class are called from the same thread. It provides identical functionality to
      44             : // base::NonThreadSafe, but it is meant to be held as a member variable, rather
      45             : // than inherited from base::NonThreadSafe.
      46             : //
      47             : // While inheriting from base::NonThreadSafe may give a clear indication about
      48             : // the thread-safety of a class, it may also lead to violations of the style
      49             : // guide with regard to multiple inheritance. The choice between having a
      50             : // ThreadChecker member and inheriting from base::NonThreadSafe should be based
      51             : // on whether:
      52             : //  - Derived classes need to know the thread they belong to, as opposed to
      53             : //    having that functionality fully encapsulated in the base class.
      54             : //  - Derived classes should be able to reassign the base class to another
      55             : //    thread, via DetachFromThread.
      56             : //
      57             : // If neither of these are true, then having a ThreadChecker member and calling
      58             : // CalledOnValidThread is the preferable solution.
      59             : //
      60             : // Example:
      61             : // class MyClass {
      62             : //  public:
      63             : //   void Foo() {
      64             : //     RTC_DCHECK(thread_checker_.CalledOnValidThread());
      65             : //     ... (do stuff) ...
      66             : //   }
      67             : //
      68             : //  private:
      69             : //   ThreadChecker thread_checker_;
      70             : // }
      71             : //
      72             : // In Release mode, CalledOnValidThread will always return true.
      73             : #if ENABLE_THREAD_CHECKER
      74           0 : class LOCKABLE ThreadChecker : public ThreadCheckerImpl {
      75             : };
      76             : #else
      77             : class LOCKABLE ThreadChecker : public ThreadCheckerDoNothing {
      78             : };
      79             : #endif  // ENABLE_THREAD_CHECKER
      80             : 
      81             : #undef ENABLE_THREAD_CHECKER
      82             : 
      83             : namespace internal {
      84             : class SCOPED_LOCKABLE AnnounceOnThread {
      85             :  public:
      86             :   template<typename ThreadLikeObject>
      87           0 :   explicit AnnounceOnThread(const ThreadLikeObject* thread_like_object)
      88           0 :       EXCLUSIVE_LOCK_FUNCTION(thread_like_object) {}
      89           0 :   ~AnnounceOnThread() UNLOCK_FUNCTION() {}
      90             : 
      91             :   template<typename ThreadLikeObject>
      92           0 :   static bool IsCurrent(const ThreadLikeObject* thread_like_object) {
      93           0 :     return thread_like_object->IsCurrent();
      94             :   }
      95           0 :   static bool IsCurrent(const rtc::ThreadChecker* checker) {
      96           0 :     return checker->CalledOnValidThread();
      97             :   }
      98             : 
      99             :  private:
     100             :   RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(AnnounceOnThread);
     101             : };
     102             : 
     103             : }  // namespace internal
     104             : }  // namespace rtc
     105             : 
     106             : // RUN_ON/ACCESS_ON/RTC_DCHECK_RUN_ON macros allows to annotate variables are
     107             : // accessed from same thread/task queue.
     108             : // Using tools designed to check mutexes, it checks at compile time everywhere
     109             : // variable is access, there is a run-time dcheck thread/task queue is correct.
     110             : //
     111             : // class ExampleThread {
     112             : //  public:
     113             : //   void NeedVar1() {
     114             : //     RTC_DCHECK_RUN_ON(network_thread_);
     115             : //     transport_->Send();
     116             : //   }
     117             : //
     118             : //  private:
     119             : //   rtc::Thread* network_thread_;
     120             : //   int transport_ ACCESS_ON(network_thread_);
     121             : // };
     122             : //
     123             : // class ExampleThreadChecker {
     124             : //  public:
     125             : //   int CalledFromPacer() RUN_ON(pacer_thread_checker_) {
     126             : //     return var2_;
     127             : //   }
     128             : //
     129             : //   void CallMeFromPacer() {
     130             : //     RTC_DCHECK_RUN_ON(&pacer_thread_checker_)
     131             : //        << "Should be called from pacer";
     132             : //     CalledFromPacer();
     133             : //   }
     134             : //
     135             : //  private:
     136             : //   int pacer_var_ ACCESS_ON(pacer_thread_checker_);
     137             : //   rtc::ThreadChecker pacer_thread_checker_;
     138             : // };
     139             : //
     140             : // class TaskQueueExample {
     141             : //  public:
     142             : //   class Encoder {
     143             : //    public:
     144             : //     rtc::TaskQueue* Queue() { return encoder_queue_; }
     145             : //     void Encode() {
     146             : //       RTC_DCHECK_RUN_ON(encoder_queue_);
     147             : //       DoSomething(var_);
     148             : //     }
     149             : //
     150             : //    private:
     151             : //     rtc::TaskQueue* const encoder_queue_;
     152             : //     Frame var_ ACCESS_ON(encoder_queue_);
     153             : //   };
     154             : //
     155             : //   void Encode() {
     156             : //     // Will fail at runtime when DCHECK is enabled:
     157             : //     // encoder_->Encode();
     158             : //     // Will work:
     159             : //     rtc::scoped_ref_ptr<Encoder> encoder = encoder_;
     160             : //     encoder_->Queue()->PostTask([encoder] { encoder->Encode(); });
     161             : //   }
     162             : //
     163             : //  private:
     164             : //   rtc::scoped_ref_ptr<Encoder> encoder_;
     165             : // }
     166             : 
     167             : // Document if a variable/field is not shared and should be accessed from
     168             : // same thread/task queue.
     169             : #define ACCESS_ON(x) THREAD_ANNOTATION_ATTRIBUTE__(guarded_by(x))
     170             : 
     171             : // Document if a function expected to be called from same thread/task queue.
     172             : #define RUN_ON(x) THREAD_ANNOTATION_ATTRIBUTE__(exclusive_locks_required(x))
     173             : 
     174             : #define RTC_DCHECK_RUN_ON(thread_like_object) \
     175             :   rtc::internal::AnnounceOnThread thread_announcer(thread_like_object); \
     176             :   RTC_DCHECK(rtc::internal::AnnounceOnThread::IsCurrent(thread_like_object))
     177             : 
     178             : #endif  // WEBRTC_BASE_THREAD_CHECKER_H_

Generated by: LCOV version 1.13