summaryrefslogtreecommitdiff
path: root/chromium/components/scheduler/renderer/throttling_helper.h
blob: d41ab6502889b6ad32fd6fa863f5ae8e2fdbe67b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
// Copyright 2015 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 COMPONENTS_SCHEDULER_RENDERER_THROTTLING_HELPER_H_
#define COMPONENTS_SCHEDULER_RENDERER_THROTTLING_HELPER_H_

#include <set>

#include "base/macros.h"
#include "components/scheduler/base/cancelable_closure_holder.h"
#include "components/scheduler/base/time_domain.h"
#include "components/scheduler/scheduler_export.h"
#include "third_party/WebKit/public/platform/WebViewScheduler.h"

namespace scheduler {

class RendererSchedulerImpl;
class ThrottledTimeDomain;
class WebFrameSchedulerImpl;

class SCHEDULER_EXPORT ThrottlingHelper : public TimeDomain::Observer {
 public:
  ThrottlingHelper(RendererSchedulerImpl* renderer_scheduler,
                   const char* tracing_category);

  ~ThrottlingHelper() override;

  // TimeDomain::Observer implementation:
  void OnTimeDomainHasImmediateWork() override;
  void OnTimeDomainHasDelayedWork() override;

  // Increments the throttled refcount and causes |task_queue| to be throttled
  // if its not already throttled.
  void IncreaseThrottleRefCount(TaskQueue* task_queue);

  // If the refcouint is non-zero it's decremented.  If the throttled refcount
  // becomes zero then |task_queue| is unthrottled.  If the refcount was already
  // zero this function does nothing.
  void DecreaseThrottleRefCount(TaskQueue* task_queue);

  // Removes |task_queue| from |throttled_queues_|.
  void UnregisterTaskQueue(TaskQueue* task_queue);

  const ThrottledTimeDomain* time_domain() const { return time_domain_.get(); }

  static base::TimeTicks ThrottledRunTime(base::TimeTicks unthrottled_runtime);

  const scoped_refptr<TaskQueue>& task_runner() const { return task_runner_; }

 private:
  using TaskQueueMap = std::map<TaskQueue*, size_t>;

  void PumpThrottledTasks();

  // Note |unthrottled_runtime| might be in the past. When this happens we
  // compute the delay to the next runtime based on now rather than
  // unthrottled_runtime.
  void MaybeSchedulePumpThrottledTasksLocked(
      const tracked_objects::Location& from_here,
      base::TimeTicks now,
      base::TimeTicks unthrottled_runtime);

  TaskQueueMap throttled_queues_;
  base::Closure forward_immediate_work_closure_;
  scoped_refptr<TaskQueue> task_runner_;
  RendererSchedulerImpl* renderer_scheduler_;  // NOT OWNED
  base::TickClock* tick_clock_;                // NOT OWNED
  const char* tracing_category_;               // NOT OWNED
  scoped_ptr<ThrottledTimeDomain> time_domain_;

  CancelableClosureHolder suspend_timers_when_backgrounded_closure_;
  base::TimeTicks pending_pump_throttled_tasks_runtime_;

  base::WeakPtrFactory<ThrottlingHelper> weak_factory_;

  DISALLOW_COPY_AND_ASSIGN(ThrottlingHelper);
};

}  // namespace scheduler

#endif  // COMPONENTS_SCHEDULER_RENDERER_THROTTLING_HELPER_H_