Index: test/inspector-protocol/task-runner.cc |
diff --git a/test/inspector-protocol/task-runner.cc b/test/inspector-protocol/task-runner.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..fc752909e19dce7b59424e97e0fbba6bbd03b599 |
--- /dev/null |
+++ b/test/inspector-protocol/task-runner.cc |
@@ -0,0 +1,117 @@ |
+// Copyright 2016 the V8 project authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include "test/inspector-protocol/task-runner.h" |
+ |
+#include "src/inspector/string-util.h" |
+ |
+namespace { |
+const int kTaskQueueIndex = 2; |
+} // namespace |
+ |
+TaskScope::TaskScope(v8::Isolate* isolate, |
+ const v8::Global<v8::Context>& context) |
+ : isolate_(isolate), |
+ isolate_scope_(isolate), |
+ handle_scope_(isolate), |
+ context_(context.Get(isolate)), |
+ context_scope_(context_), |
+ microtasks_scope_(isolate_, v8::MicrotasksScope::kRunMicrotasks), |
+ try_catch_(isolate_) {} |
+ |
+TaskScope::~TaskScope() { |
+ if (try_catch_.HasCaught()) { |
+ v8_inspector::String16 message = |
+ v8_inspector::toProtocolString(try_catch_.Message()->Get()); |
+ fprintf(stderr, "Unhandle exception: %s\n", message.utf8().data()); |
+ fflush(stdout); |
+ fflush(stderr); |
+ _exit(0); |
+ } |
+} |
+ |
+ExecuteStringTask::ExecuteStringTask(const v8_inspector::StringView& expression) |
+ : expression_(toString16(expression)) {} |
+ |
+void ExecuteStringTask::Run(v8::Isolate* isolate, |
+ const v8::Global<v8::Context>& global_context) { |
+ TaskScope task_scope(isolate, global_context); |
+ v8::Local<v8::Context> context = task_scope.context(); |
+ v8::ScriptOrigin origin(v8::String::Empty(isolate)); |
+ v8::ScriptCompiler::Source scriptSource(toV8String(isolate, expression_), |
+ origin); |
+ v8::Local<v8::Script> script; |
+ if (!v8::ScriptCompiler::Compile(context, &scriptSource).ToLocal(&script)) |
+ return; |
+ v8::MaybeLocal<v8::Value> result; |
dgozman
2016/09/23 03:09:55
... = script->Run(context);
kozy
2016/09/23 17:05:19
I split it into two lines to avoid redundant check
|
+ result = script->Run(context); |
+} |
+ |
+TaskQueue::TaskQueue() : process_queue_semaphore_(0) {} |
+ |
+TaskQueue::~TaskQueue() {} |
+ |
+void TaskQueue::Append(Task* task) { |
+ queue_.Enqueue(task); |
+ process_queue_semaphore_.Signal(); |
+} |
+ |
+Task* TaskQueue::GetNext(bool only_protocol) { |
+ for (;;) { |
+ if (only_protocol) { |
+ for (;;) { |
+ Task* task = nullptr; |
+ if (!queue_.Dequeue(&task)) break; |
+ if (task->is_protocol_task()) return task; |
+ deffered_queue_.Enqueue(task); |
+ } |
+ } else { |
+ Task* task = nullptr; |
+ if (deffered_queue_.Dequeue(&task)) return task; |
+ if (queue_.Dequeue(&task)) return task; |
+ } |
+ process_queue_semaphore_.Wait(); |
+ } |
+} |
+ |
+void TaskQueue::SetContext(v8::Local<v8::Context> context) { |
+ context->SetAlignedPointerInEmbedderData(kTaskQueueIndex, this); |
+} |
+ |
+TaskQueue* TaskQueue::FromContext(v8::Local<v8::Context> context) { |
+ return static_cast<TaskQueue*>( |
+ context->GetAlignedPointerFromEmbedderData(kTaskQueueIndex)); |
+} |
+ |
+TaskRunner::TaskRunner(TaskQueue* queue) |
+ : Thread(Options("Task Runner")), |
+ queue_(queue), |
+ state_(TaskRunner::kRunning), |
+ isolate_(NULL) { |
dgozman
2016/09/23 03:09:55
nullptr
kozy
2016/09/23 17:05:20
Done.
|
+ Start(); |
+} |
+ |
+TaskRunner::~TaskRunner() { Join(); } |
+ |
+void TaskRunner::SetContext(v8::Local<v8::Context> context) { |
dgozman
2016/09/23 03:09:56
Why not pass in constructor?
kozy
2016/09/23 17:05:20
Moved isolate and context initialization logic int
|
+ isolate_ = context->GetIsolate(); |
+ context_.Reset(isolate_, context); |
+} |
+ |
+void TaskRunner::Run() { |
+ while (state_.Value() == kRunning) { |
+ Task* task = queue_->GetNext(false); |
dgozman
2016/09/23 03:09:56
Looks like this runs forever even if Stop was call
kozy
2016/09/23 17:05:20
I expose RunMessageLoop and QuitMessageLoop interf
|
+ if (!task) return; |
+ if (isolate_) |
+ task->Run(isolate_, context_); |
dgozman
2016/09/23 03:09:55
Why two different types of tasks?
kozy
2016/09/23 17:05:19
Removed.
|
+ else |
+ task->Run(); |
+ delete task; |
+ } |
+} |
+ |
+void TaskRunner::Stop() { state_.SetValue(kStopRequested); } |
+ |
+// main to make compiler happy before other patch will be landed. |
+int main(int argc, char* argv[]) { return 0; } |