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; SchedulerLock(const SchedulerLock * predecessor)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: AutoSchedulerLock(SchedulerLock & lock)70 explicit AutoSchedulerLock(SchedulerLock& lock) : lock_(lock) { 71 lock_.Acquire(); 72 } 73 ~AutoSchedulerLock()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