GCC Code Coverage Report
Directory: ../ Exec Total Coverage
File: /home/iojs/build/workspace/node-test-commit-linux-coverage-daily/nodes/benchmark/out/../src/node_platform.h Lines: 5 6 83.3 %
Date: 2019-03-02 22:23:06 Branches: 1 2 50.0 %

Line Branch Exec Source
1
#ifndef SRC_NODE_PLATFORM_H_
2
#define SRC_NODE_PLATFORM_H_
3
4
#if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
5
6
#include <queue>
7
#include <unordered_map>
8
#include <vector>
9
#include <functional>
10
11
#include "libplatform/libplatform.h"
12
#include "node.h"
13
#include "node_mutex.h"
14
#include "tracing/agent.h"
15
#include "uv.h"
16
17
namespace node {
18
19
class NodePlatform;
20
class IsolateData;
21
class PerIsolatePlatformData;
22
23
template <class T>
24
class TaskQueue {
25
 public:
26
  TaskQueue();
27
16334
  ~TaskQueue() {}
28
29
  void Push(std::unique_ptr<T> task);
30
  std::unique_ptr<T> Pop();
31
  std::unique_ptr<T> BlockingPop();
32
  std::queue<std::unique_ptr<T>> PopAll();
33
  void NotifyOfCompletion();
34
  void BlockingDrain();
35
  void Stop();
36
37
 private:
38
  Mutex lock_;
39
  ConditionVariable tasks_available_;
40
  ConditionVariable tasks_drained_;
41
  int outstanding_tasks_;
42
  bool stopped_;
43
  std::queue<std::unique_ptr<T>> task_queue_;
44
};
45
46
140
struct DelayedTask {
47
  std::unique_ptr<v8::Task> task;
48
  uv_timer_t timer;
49
  double timeout;
50
  std::shared_ptr<PerIsolatePlatformData> platform_data;
51
};
52
53
// This acts as the foreground task runner for a given Isolate.
54
class PerIsolatePlatformData :
55
    public v8::TaskRunner,
56
    public std::enable_shared_from_this<PerIsolatePlatformData> {
57
 public:
58
  PerIsolatePlatformData(v8::Isolate* isolate, uv_loop_t* loop);
59
  ~PerIsolatePlatformData() override;
60
61
  void PostTask(std::unique_ptr<v8::Task> task) override;
62
  void PostIdleTask(std::unique_ptr<v8::IdleTask> task) override;
63
  void PostDelayedTask(std::unique_ptr<v8::Task> task,
64
                       double delay_in_seconds) override;
65
  bool IdleTasksEnabled() override { return false; };
66
67
  void Shutdown();
68
69
  void ref();
70
  int unref();
71
72
  // Returns true if work was dispatched or executed. New tasks that are
73
  // posted during flushing of the queue are postponed until the next
74
  // flushing.
75
  bool FlushForegroundTasksInternal();
76
  void CancelPendingDelayedTasks();
77
78
4420
  const uv_loop_t* event_loop() const { return loop_; }
79
80
 private:
81
  void DeleteFromScheduledTasks(DelayedTask* task);
82
83
  static void FlushTasks(uv_async_t* handle);
84
  static void RunForegroundTask(std::unique_ptr<v8::Task> task);
85
  static void RunForegroundTask(uv_timer_t* timer);
86
87
  int ref_count_ = 1;
88
  uv_loop_t* const loop_;
89
  uv_async_t* flush_tasks_ = nullptr;
90
  TaskQueue<v8::Task> foreground_tasks_;
91
  TaskQueue<DelayedTask> foreground_delayed_tasks_;
92
93
  // Use a custom deleter because libuv needs to close the handle first.
94
  typedef std::unique_ptr<DelayedTask, std::function<void(DelayedTask*)>>
95
      DelayedTaskPointer;
96
  std::vector<DelayedTaskPointer> scheduled_delayed_tasks_;
97
};
98
99
// This acts as the single worker thread task runner for all Isolates.
100
4242
class WorkerThreadsTaskRunner {
101
 public:
102
  explicit WorkerThreadsTaskRunner(int thread_pool_size);
103
104
  void PostTask(std::unique_ptr<v8::Task> task);
105
  void PostDelayedTask(std::unique_ptr<v8::Task> task,
106
                       double delay_in_seconds);
107
108
  void BlockingDrain();
109
  void Shutdown();
110
111
  int NumberOfWorkerThreads() const;
112
113
 private:
114
  TaskQueue<v8::Task> pending_worker_tasks_;
115
116
  class DelayedTaskScheduler;
117
  std::unique_ptr<DelayedTaskScheduler> delayed_task_scheduler_;
118
119
  std::vector<std::unique_ptr<uv_thread_t>> threads_;
120
};
121
122
class NodePlatform : public MultiIsolatePlatform {
123
 public:
124
  NodePlatform(int thread_pool_size,
125
               node::tracing::TracingController* tracing_controller);
126
8484
  ~NodePlatform() override {}
127
128
  void DrainTasks(v8::Isolate* isolate) override;
129
  void CancelPendingDelayedTasks(v8::Isolate* isolate) override;
130
  void Shutdown();
131
132
  // v8::Platform implementation.
133
  int NumberOfWorkerThreads() override;
134
  void CallOnWorkerThread(std::unique_ptr<v8::Task> task) override;
135
  void CallDelayedOnWorkerThread(std::unique_ptr<v8::Task> task,
136
                                 double delay_in_seconds) override;
137
  void CallOnForegroundThread(v8::Isolate* isolate, v8::Task* task) override;
138
  void CallDelayedOnForegroundThread(v8::Isolate* isolate, v8::Task* task,
139
                                     double delay_in_seconds) override;
140
  bool IdleTasksEnabled(v8::Isolate* isolate) override;
141
  double MonotonicallyIncreasingTime() override;
142
  double CurrentClockTimeMillis() override;
143
  node::tracing::TracingController* GetTracingController() override;
144
  bool FlushForegroundTasks(v8::Isolate* isolate) override;
145
146
  void RegisterIsolate(v8::Isolate* isolate, uv_loop_t* loop) override;
147
  void UnregisterIsolate(v8::Isolate* isolate) override;
148
149
  std::shared_ptr<v8::TaskRunner> GetForegroundTaskRunner(
150
      v8::Isolate* isolate) override;
151
152
 private:
153
  std::shared_ptr<PerIsolatePlatformData> ForIsolate(v8::Isolate* isolate);
154
155
  Mutex per_isolate_mutex_;
156
  std::unordered_map<v8::Isolate*,
157
                     std::shared_ptr<PerIsolatePlatformData>> per_isolate_;
158
159
  node::tracing::TracingController* tracing_controller_;
160
  std::shared_ptr<WorkerThreadsTaskRunner> worker_thread_task_runner_;
161
};
162
163
}  // namespace node
164
165
#endif  // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
166
167
#endif  // SRC_NODE_PLATFORM_H_