Home | History | Annotate | Download | only in js
      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 
     10 namespace mojo {
     11 namespace js {
     12 
     13 namespace {
     14 
     15 v8::Handle<v8::String> GetHiddenPropertyName(v8::Isolate* isolate) {
     16   return gin::StringToSymbol(isolate, "::mojo::js::WaitingCallback");
     17 }
     18 
     19 }  // namespace
     20 
     21 gin::WrapperInfo WaitingCallback::kWrapperInfo = { gin::kEmbedderNativeGin };
     22 
     23 // static
     24 gin::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 
     40 void WaitingCallback::Cancel() {
     41   if (!wait_id_)
     42     return;
     43 
     44   Environment::GetDefaultAsyncWaiter()->CancelWait(wait_id_);
     45   wait_id_ = 0;
     46 }
     47 
     48 WaitingCallback::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 
     56 WaitingCallback::~WaitingCallback() {
     57   Cancel();
     58 }
     59 
     60 // static
     61 void WaitingCallback::CallOnHandleReady(void* closure, MojoResult result) {
     62   static_cast<WaitingCallback*>(closure)->OnHandleReady(result);
     63 }
     64 
     65 void 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