diff options
author | hansmuller <hansmuller@chromium.org> | 2014-09-25 11:41:18 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2014-09-25 18:42:04 +0000 |
commit | 5a5cb9e791961a2491c4269fc0f2144f385dc173 (patch) | |
tree | 14b352dc925a64dc7ef52df6b38991cb1ee79dde /gin | |
parent | 1c863aa414026f2ece4ce5b930bcbce1cd07d6f0 (diff) | |
download | chromium_src-5a5cb9e791961a2491c4269fc0f2144f385dc173.zip chromium_src-5a5cb9e791961a2491c4269fc0f2144f385dc173.tar.gz chromium_src-5a5cb9e791961a2491c4269fc0f2144f385dc173.tar.bz2 |
Mojo JS bindings: draining a DataPipe
Add a drainData(dataPipeHandle) utility function to the Mojo JS core module.
The drainData() function asynchronously reads from the data pipe until the remote handle is closed or an error occurs. A Promise is returned whose settled value is an object like this: {result: core.RESULT_OK, buffer: dataArrayBuffer}. If the read failed, then the result will be the actual error code and the buffer will contain whatever was read before the error occurred. The drainData dataPipeHandle argument is closed automatically.
BUG=414338
Review URL: https://codereview.chromium.org/577733002
Cr-Commit-Position: refs/heads/master@{#296750}
Diffstat (limited to 'gin')
-rw-r--r-- | gin/BUILD.gn | 2 | ||||
-rw-r--r-- | gin/gin.gyp | 2 | ||||
-rw-r--r-- | gin/isolate_holder.cc | 16 | ||||
-rw-r--r-- | gin/public/isolate_holder.h | 14 | ||||
-rw-r--r-- | gin/run_microtasks_observer.cc | 21 | ||||
-rw-r--r-- | gin/run_microtasks_observer.h | 30 |
6 files changed, 85 insertions, 0 deletions
diff --git a/gin/BUILD.gn b/gin/BUILD.gn index 21807ae..b352c3a 100644 --- a/gin/BUILD.gn +++ b/gin/BUILD.gn @@ -47,6 +47,8 @@ component("gin") { "public/wrapper_info.h", "runner.cc", "runner.h", + "run_microtasks_observer.cc", + "run_microtasks_observer.h", "shell_runner.cc", "shell_runner.h", "try_catch.cc", diff --git a/gin/gin.gyp b/gin/gin.gyp index caa2ba4..b38dc85 100644 --- a/gin/gin.gyp +++ b/gin/gin.gyp @@ -67,6 +67,8 @@ 'public/wrapper_info.h', 'runner.cc', 'runner.h', + 'run_microtasks_observer.cc', + 'run_microtasks_observer.h', 'shell_runner.cc', 'shell_runner.h', 'try_catch.cc', diff --git a/gin/isolate_holder.cc b/gin/isolate_holder.cc index db4473e..00e9d84 100644 --- a/gin/isolate_holder.cc +++ b/gin/isolate_holder.cc @@ -8,6 +8,7 @@ #include <string.h> #include "base/logging.h" +#include "base/message_loop/message_loop.h" #include "base/rand_util.h" #include "base/sys_info.h" #include "gin/array_buffer.h" @@ -15,6 +16,7 @@ #include "gin/function_template.h" #include "gin/per_isolate_data.h" #include "gin/public/v8_platform.h" +#include "gin/run_microtasks_observer.h" namespace gin { @@ -43,6 +45,8 @@ IsolateHolder::IsolateHolder() { } IsolateHolder::~IsolateHolder() { + if (task_observer_.get()) + base::MessageLoop::current()->RemoveTaskObserver(task_observer_.get()); isolate_data_.reset(); isolate_->Dispose(); } @@ -66,4 +70,16 @@ void IsolateHolder::Initialize(ScriptMode mode, v8_is_initialized = true; } +void IsolateHolder::AddRunMicrotasksObserver() { + DCHECK(!task_observer_.get()); + task_observer_.reset(new RunMicrotasksObserver(isolate_));; + base::MessageLoop::current()->AddTaskObserver(task_observer_.get()); +} + +void IsolateHolder::RemoveRunMicrotasksObserver() { + DCHECK(task_observer_.get()); + base::MessageLoop::current()->RemoveTaskObserver(task_observer_.get()); + task_observer_.reset(); +} + } // namespace gin diff --git a/gin/public/isolate_holder.h b/gin/public/isolate_holder.h index da65fac..29cc208 100644 --- a/gin/public/isolate_holder.h +++ b/gin/public/isolate_holder.h @@ -13,6 +13,7 @@ namespace gin { class PerIsolateData; +class RunMicrotasksObserver; // To embed Gin, first initialize gin using IsolateHolder::Initialize and then // create an instance of IsolateHolder to hold the v8::Isolate in which you @@ -36,9 +37,22 @@ class GIN_EXPORT IsolateHolder { v8::Isolate* isolate() { return isolate_; } + // The implementations of Object.observe() and Promise enqueue v8 Microtasks + // that should be executed just before control is returned to the message + // loop. This method adds a MessageLoop TaskObserver which runs any pending + // Microtasks each time a Task is completed. This method should be called + // once, when a MessageLoop is created and it should be called on the + // MessageLoop's thread. + void AddRunMicrotasksObserver(); + + // This method should also only be called once, and on the MessageLoop's + // thread. + void RemoveRunMicrotasksObserver(); + private: v8::Isolate* isolate_; scoped_ptr<PerIsolateData> isolate_data_; + scoped_ptr<RunMicrotasksObserver> task_observer_; DISALLOW_COPY_AND_ASSIGN(IsolateHolder); }; diff --git a/gin/run_microtasks_observer.cc b/gin/run_microtasks_observer.cc new file mode 100644 index 0000000..f453a66 --- /dev/null +++ b/gin/run_microtasks_observer.cc @@ -0,0 +1,21 @@ +// Copyright 2014 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. + +#include "gin/run_microtasks_observer.h" + +namespace gin { + +RunMicrotasksObserver::RunMicrotasksObserver(v8::Isolate* isolate) + : isolate_(isolate) { +} + +void RunMicrotasksObserver::WillProcessTask(const base::PendingTask& task) { +} + +void RunMicrotasksObserver::DidProcessTask(const base::PendingTask& task) { + v8::Isolate::Scope scope(isolate_); + isolate_->RunMicrotasks(); +} + +} // namespace gin diff --git a/gin/run_microtasks_observer.h b/gin/run_microtasks_observer.h new file mode 100644 index 0000000..e848239 --- /dev/null +++ b/gin/run_microtasks_observer.h @@ -0,0 +1,30 @@ +// Copyright 2014 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 GIN_RUN_MICROTASKS_OBSERVER_H_ +#define GIN_RUN_MICROTASKS_OBSERVER_H_ + +#include "base/message_loop/message_loop.h" +#include "v8/include/v8.h" + +namespace gin { + +// Runs any pending v8 Microtasks each time a task is completed. +// TODO(hansmuller); At some point perhaps this can be replaced with +// the (currently experimental) Isolate::SetAutorunMicrotasks() method. + +class RunMicrotasksObserver : public base::MessageLoop::TaskObserver { + public: + RunMicrotasksObserver(v8::Isolate* isolate); + + virtual void WillProcessTask(const base::PendingTask& pending_task) OVERRIDE; + virtual void DidProcessTask(const base::PendingTask& pending_task) OVERRIDE; + + private: + v8::Isolate* isolate_; +}; + +} // namespace gin + +#endif // GIN_RUN_MICROTASKS_OBSERVER_H_ |