summaryrefslogtreecommitdiff
path: root/chromium/third_party/blink/renderer/core/dom/scripted_idle_task_controller.h
blob: 0444edfea701437271d69bdda84af2f6a70b8d49 (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
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
// 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 THIRD_PARTY_BLINK_RENDERER_CORE_DOM_SCRIPTED_IDLE_TASK_CONTROLLER_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_DOM_SCRIPTED_IDLE_TASK_CONTROLLER_H_

#include "third_party/blink/renderer/bindings/core/v8/v8_idle_request_callback.h"
#include "third_party/blink/renderer/core/dom/idle_deadline.h"
#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_state_observer.h"
#include "third_party/blink/renderer/core/probe/async_task_id.h"
#include "third_party/blink/renderer/platform/bindings/name_client.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
#include "third_party/blink/renderer/platform/timer.h"
#include "third_party/blink/renderer/platform/wtf/vector.h"

namespace blink {
namespace internal {
class IdleRequestCallbackWrapper;
}

class ExecutionContext;
class IdleRequestOptions;
class ThreadScheduler;

// |IdleTask| is an interface type which generalizes tasks which are invoked
// on idle. The tasks need to define what to do on idle in |invoke|.
class IdleTask : public GarbageCollected<IdleTask>, public NameClient {
 public:
  virtual void Trace(Visitor* visitor) const {}
  const char* NameInHeapSnapshot() const override { return "IdleTask"; }
  ~IdleTask() override = default;
  virtual void invoke(IdleDeadline*) = 0;
  probe::AsyncTaskId* async_task_id() { return &async_task_id_; }

 private:
  probe::AsyncTaskId async_task_id_;
};

// |V8IdleTask| is the adapter class for the conversion from
// |V8IdleRequestCallback| to |IdleTask|.
class V8IdleTask : public IdleTask {
 public:
  static V8IdleTask* Create(V8IdleRequestCallback* callback) {
    return MakeGarbageCollected<V8IdleTask>(callback);
  }

  explicit V8IdleTask(V8IdleRequestCallback*);
  ~V8IdleTask() override = default;

  void invoke(IdleDeadline*) override;
  void Trace(Visitor*) const override;

 private:
  Member<V8IdleRequestCallback> callback_;
};

class CORE_EXPORT ScriptedIdleTaskController
    : public GarbageCollected<ScriptedIdleTaskController>,
      public ExecutionContextLifecycleStateObserver,
      public NameClient {
 public:
  static ScriptedIdleTaskController* Create(ExecutionContext* context) {
    ScriptedIdleTaskController* controller =
        MakeGarbageCollected<ScriptedIdleTaskController>(context);
    controller->UpdateStateIfNeeded();
    return controller;
  }

  explicit ScriptedIdleTaskController(ExecutionContext*);
  ~ScriptedIdleTaskController() override;

  void Trace(Visitor*) const override;
  const char* NameInHeapSnapshot() const override {
    return "ScriptedIdleTaskController";
  }

  using CallbackId = int;

  int RegisterCallback(IdleTask*, const IdleRequestOptions*);
  void CancelCallback(CallbackId);

  // ExecutionContextLifecycleStateObserver interface.
  void ContextDestroyed() override;
  void ContextLifecycleStateChanged(mojom::FrameLifecycleState) override;

  void CallbackFired(CallbackId,
                     base::TimeTicks deadline,
                     IdleDeadline::CallbackType);

 private:
  friend class internal::IdleRequestCallbackWrapper;

  void ContextPaused();
  void ContextUnpaused();
  void ScheduleCallback(scoped_refptr<internal::IdleRequestCallbackWrapper>,
                        uint32_t timeout_millis);

  int NextCallbackId();

  bool IsValidCallbackId(int id) {
    using Traits = HashTraits<CallbackId>;
    return !Traits::IsDeletedValue(id) &&
           !WTF::IsHashTraitsEmptyValue<Traits, CallbackId>(id);
  }

  void RunCallback(CallbackId,
                   base::TimeTicks deadline,
                   IdleDeadline::CallbackType);

  ThreadScheduler* scheduler_;  // Not owned.
  HeapHashMap<CallbackId, Member<IdleTask>> idle_tasks_;
  Vector<CallbackId> pending_timeouts_;
  CallbackId next_callback_id_;
  bool paused_;
};

}  // namespace blink

#endif  // THIRD_PARTY_BLINK_RENDERER_CORE_DOM_SCRIPTED_IDLE_TASK_CONTROLLER_H_