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