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 16namespace base { 17namespace 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() 49class SchedulerLock : public SchedulerLockImpl { 50 public: 51 SchedulerLock() = default; 52 explicit SchedulerLock(const SchedulerLock* predecessor) 53 : SchedulerLockImpl(predecessor) {} 54}; 55#else // DCHECK_IS_ON() 56class 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. 68class 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