1// Copyright 2017 the V8 project 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 V8_LIBPLATFORM_DEFAULT_FOREGROUND_TASK_RUNNER_H_
6#define V8_LIBPLATFORM_DEFAULT_FOREGROUND_TASK_RUNNER_H_
7
8#include <queue>
9
10#include "include/libplatform/libplatform.h"
11#include "include/v8-platform.h"
12#include "src/base/platform/condition-variable.h"
13#include "src/base/platform/mutex.h"
14
15namespace v8 {
16namespace platform {
17
18class V8_PLATFORM_EXPORT DefaultForegroundTaskRunner
19 : public NON_EXPORTED_BASE(TaskRunner) {
20 public:
21 using TimeFunction = double (*)();
22
23 DefaultForegroundTaskRunner(IdleTaskSupport idle_task_support,
24 TimeFunction time_function);
25
26 void Terminate();
27
28 std::unique_ptr<Task> PopTaskFromQueue(MessageLoopBehavior wait_for_work);
29
30 std::unique_ptr<IdleTask> PopTaskFromIdleQueue();
31
32 void WaitForTaskLocked(const base::MutexGuard&);
33
34 double MonotonicallyIncreasingTime();
35
36 // v8::TaskRunner implementation.
37 void PostTask(std::unique_ptr<Task> task) override;
38
39 void PostDelayedTask(std::unique_ptr<Task> task,
40 double delay_in_seconds) override;
41
42 void PostIdleTask(std::unique_ptr<IdleTask> task) override;
43
44 bool IdleTasksEnabled() override;
45
46 private:
47 // The same as PostTask, but the lock is already held by the caller. The
48 // {guard} parameter should make sure that the caller is holding the lock.
49 void PostTaskLocked(std::unique_ptr<Task> task, const base::MutexGuard&);
50
51 // A caller of this function has to hold {lock_}. The {guard} parameter should
52 // make sure that the caller is holding the lock.
53 std::unique_ptr<Task> PopTaskFromDelayedQueueLocked(const base::MutexGuard&);
54
55 bool terminated_ = false;
56 base::Mutex lock_;
57 base::ConditionVariable event_loop_control_;
58 std::queue<std::unique_ptr<Task>> task_queue_;
59 IdleTaskSupport idle_task_support_;
60 std::queue<std::unique_ptr<IdleTask>> idle_task_queue_;
61
62 // Some helper constructs for the {delayed_task_queue_}.
63 using DelayedEntry = std::pair<double, std::unique_ptr<Task>>;
64 // Define a comparison operator for the delayed_task_queue_ to make sure
65 // that the unique_ptr in the DelayedEntry is not accessed in the priority
66 // queue. This is necessary because we have to reset the unique_ptr when we
67 // remove a DelayedEntry from the priority queue.
68 struct DelayedEntryCompare {
69 bool operator()(const DelayedEntry& left, const DelayedEntry& right) const {
70 return left.first > right.first;
71 }
72 };
73 std::priority_queue<DelayedEntry, std::vector<DelayedEntry>,
74 DelayedEntryCompare>
75 delayed_task_queue_;
76
77 TimeFunction time_function_;
78};
79
80} // namespace platform
81} // namespace v8
82#endif // V8_LIBPLATFORM_DEFAULT_FOREGROUND_TASK_RUNNER_H_
83