Home | History | Annotate | Download | only in task_scheduler
      1 // Copyright 2016 The Chromium 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 #ifndef BASE_TASK_SCHEDULER_SCHEDULER_LOCK_H
      6 #define BASE_TASK_SCHEDULER_SCHEDULER_LOCK_H
      7 
      8 #include <memory>
      9 
     10 #include "base/base_export.h"
     11 #include "base/macros.h"
     12 #include "base/synchronization/condition_variable.h"
     13 #include "base/synchronization/lock.h"
     14 #include "base/task_scheduler/scheduler_lock_impl.h"
     15 
     16 namespace base {
     17 namespace internal {
     18 
     19 // SchedulerLock should be used anywhere a lock would be used in the scheduler.
     20 // When DCHECK_IS_ON(), lock checking occurs. Otherwise, SchedulerLock is
     21 // equivalent to base::Lock.
     22 //
     23 // The shape of SchedulerLock is as follows:
     24 // SchedulerLock()
     25 //     Default constructor, no predecessor lock.
     26 //     DCHECKs
     27 //         On Acquisition if any scheduler lock is acquired on this thread.
     28 //
     29 // SchedulerLock(const SchedulerLock* predecessor)
     30 //     Constructor that specifies an allowed predecessor for that lock.
     31 //     DCHECKs
     32 //         On Construction if |predecessor| forms a predecessor lock cycle.
     33 //         On Acquisition if the previous lock acquired on the thread is not
     34 //             |predecessor|. Okay if there was no previous lock acquired.
     35 //
     36 // void Acquire()
     37 //     Acquires the lock.
     38 //
     39 // void Release()
     40 //     Releases the lock.
     41 //
     42 // void AssertAcquired().
     43 //     DCHECKs if the lock is not acquired.
     44 //
     45 // std::unique_ptr<ConditionVariable> CreateConditionVariable()
     46 //     Creates a condition variable using this as a lock.
     47 
     48 #if DCHECK_IS_ON()
     49 class SchedulerLock : public SchedulerLockImpl {
     50  public:
     51   SchedulerLock() = default;
     52   explicit SchedulerLock(const SchedulerLock* predecessor)
     53       : SchedulerLockImpl(predecessor) {}
     54 };
     55 #else  // DCHECK_IS_ON()
     56 class SchedulerLock : public Lock {
     57  public:
     58   SchedulerLock() = default;
     59   explicit SchedulerLock(const SchedulerLock*) {}
     60 
     61   std::unique_ptr<ConditionVariable> CreateConditionVariable() {
     62     return std::unique_ptr<ConditionVariable>(new ConditionVariable(this));
     63   }
     64 };
     65 #endif  // DCHECK_IS_ON()
     66 
     67 // Provides the same functionality as base::AutoLock for SchedulerLock.
     68 class AutoSchedulerLock {
     69  public:
     70   explicit AutoSchedulerLock(SchedulerLock& lock) : lock_(lock) {
     71     lock_.Acquire();
     72   }
     73 
     74   ~AutoSchedulerLock() {
     75     lock_.AssertAcquired();
     76     lock_.Release();
     77   }
     78 
     79  private:
     80   SchedulerLock& lock_;
     81 
     82   DISALLOW_COPY_AND_ASSIGN(AutoSchedulerLock);
     83 };
     84 
     85 }  // namespace internal
     86 }  // namespace base
     87 
     88 #endif  // BASE_TASK_SCHEDULER_SCHEDULER_LOCK_H
     89