// Copyright 2016 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef BASE_TASK_SCHEDULER_SCHEDULER_LOCK_H #define BASE_TASK_SCHEDULER_SCHEDULER_LOCK_H #include <memory> #include "base/base_export.h" #include "base/macros.h" #include "base/synchronization/condition_variable.h" #include "base/synchronization/lock.h" #include "base/task_scheduler/scheduler_lock_impl.h" namespace base { namespace internal { // SchedulerLock should be used anywhere a lock would be used in the scheduler. // When DCHECK_IS_ON(), lock checking occurs. Otherwise, SchedulerLock is // equivalent to base::Lock. // // The shape of SchedulerLock is as follows: // SchedulerLock() // Default constructor, no predecessor lock. // DCHECKs // On Acquisition if any scheduler lock is acquired on this thread. // // SchedulerLock(const SchedulerLock* predecessor) // Constructor that specifies an allowed predecessor for that lock. // DCHECKs // On Construction if |predecessor| forms a predecessor lock cycle. // On Acquisition if the previous lock acquired on the thread is not // |predecessor|. Okay if there was no previous lock acquired. // // void Acquire() // Acquires the lock. // // void Release() // Releases the lock. // // void AssertAcquired(). // DCHECKs if the lock is not acquired. // // std::unique_ptr<ConditionVariable> CreateConditionVariable() // Creates a condition variable using this as a lock. #if DCHECK_IS_ON() class SchedulerLock : public SchedulerLockImpl { public: SchedulerLock() = default; explicit SchedulerLock(const SchedulerLock* predecessor) : SchedulerLockImpl(predecessor) {} }; #else // DCHECK_IS_ON() class SchedulerLock : public Lock { public: SchedulerLock() = default; explicit SchedulerLock(const SchedulerLock*) {} std::unique_ptr<ConditionVariable> CreateConditionVariable() { return std::unique_ptr<ConditionVariable>(new ConditionVariable(this)); } }; #endif // DCHECK_IS_ON() // Provides the same functionality as base::AutoLock for SchedulerLock. class AutoSchedulerLock { public: explicit AutoSchedulerLock(SchedulerLock& lock) : lock_(lock) { lock_.Acquire(); } ~AutoSchedulerLock() { lock_.AssertAcquired(); lock_.Release(); } private: SchedulerLock& lock_; DISALLOW_COPY_AND_ASSIGN(AutoSchedulerLock); }; } // namespace internal } // namespace base #endif // BASE_TASK_SCHEDULER_SCHEDULER_LOCK_H