1// Copyright 2014 The Chromium 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#include "mojo/bindings/js/waiting_callback.h" 6 7#include "gin/per_context_data.h" 8#include "mojo/public/cpp/environment/environment.h" 9 10namespace mojo { 11namespace js { 12 13namespace { 14 15v8::Handle<v8::String> GetHiddenPropertyName(v8::Isolate* isolate) { 16 return gin::StringToSymbol(isolate, "::mojo::js::WaitingCallback"); 17} 18 19} // namespace 20 21gin::WrapperInfo WaitingCallback::kWrapperInfo = { gin::kEmbedderNativeGin }; 22 23// static 24gin::Handle<WaitingCallback> WaitingCallback::Create( 25 v8::Isolate* isolate, 26 v8::Handle<v8::Function> callback, 27 mojo::Handle handle, 28 MojoHandleSignals signals) { 29 gin::Handle<WaitingCallback> waiting_callback = 30 gin::CreateHandle(isolate, new WaitingCallback(isolate, callback)); 31 waiting_callback->wait_id_ = Environment::GetDefaultAsyncWaiter()->AsyncWait( 32 handle.value(), 33 signals, 34 MOJO_DEADLINE_INDEFINITE, 35 &WaitingCallback::CallOnHandleReady, 36 waiting_callback.get()); 37 return waiting_callback; 38} 39 40void WaitingCallback::Cancel() { 41 if (!wait_id_) 42 return; 43 44 Environment::GetDefaultAsyncWaiter()->CancelWait(wait_id_); 45 wait_id_ = 0; 46} 47 48WaitingCallback::WaitingCallback(v8::Isolate* isolate, 49 v8::Handle<v8::Function> callback) 50 : wait_id_() { 51 v8::Handle<v8::Context> context = isolate->GetCurrentContext(); 52 runner_ = gin::PerContextData::From(context)->runner()->GetWeakPtr(); 53 GetWrapper(isolate)->SetHiddenValue(GetHiddenPropertyName(isolate), callback); 54} 55 56WaitingCallback::~WaitingCallback() { 57 Cancel(); 58} 59 60// static 61void WaitingCallback::CallOnHandleReady(void* closure, MojoResult result) { 62 static_cast<WaitingCallback*>(closure)->OnHandleReady(result); 63} 64 65void WaitingCallback::OnHandleReady(MojoResult result) { 66 wait_id_ = 0; 67 68 if (!runner_) 69 return; 70 71 gin::Runner::Scope scope(runner_.get()); 72 v8::Isolate* isolate = runner_->GetContextHolder()->isolate(); 73 74 v8::Handle<v8::Value> hidden_value = 75 GetWrapper(isolate)->GetHiddenValue(GetHiddenPropertyName(isolate)); 76 v8::Handle<v8::Function> callback; 77 CHECK(gin::ConvertFromV8(isolate, hidden_value, &callback)); 78 79 v8::Handle<v8::Value> args[] = { gin::ConvertToV8(isolate, result) }; 80 runner_->Call(callback, runner_->global(), 1, args); 81} 82 83} // namespace js 84} // namespace mojo 85