Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(220)

Side by Side Diff: mojo/edk/js/waiting_callback.cc

Issue 1777673003: [mojo-bindings] Use Watcher API for JS bindings (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "mojo/edk/js/waiting_callback.h" 5 #include "mojo/edk/js/waiting_callback.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/message_loop/message_loop.h" 8 #include "base/message_loop/message_loop.h"
9 #include "gin/per_context_data.h" 9 #include "gin/per_context_data.h"
10 10
(...skipping 10 matching lines...) Expand all
21 21
22 } // namespace 22 } // namespace
23 23
24 gin::WrapperInfo WaitingCallback::kWrapperInfo = { gin::kEmbedderNativeGin }; 24 gin::WrapperInfo WaitingCallback::kWrapperInfo = { gin::kEmbedderNativeGin };
25 25
26 // static 26 // static
27 gin::Handle<WaitingCallback> WaitingCallback::Create( 27 gin::Handle<WaitingCallback> WaitingCallback::Create(
28 v8::Isolate* isolate, 28 v8::Isolate* isolate,
29 v8::Handle<v8::Function> callback, 29 v8::Handle<v8::Function> callback,
30 gin::Handle<HandleWrapper> handle_wrapper, 30 gin::Handle<HandleWrapper> handle_wrapper,
31 MojoHandleSignals signals) { 31 MojoHandleSignals signals,
32 bool one_shot) {
32 gin::Handle<WaitingCallback> waiting_callback = gin::CreateHandle( 33 gin::Handle<WaitingCallback> waiting_callback = gin::CreateHandle(
33 isolate, new WaitingCallback(isolate, callback, handle_wrapper)); 34 isolate,
35 new WaitingCallback(isolate, callback, handle_wrapper, one_shot));
34 36
35 waiting_callback->handle_watcher_.Start( 37 if (one_shot) {
36 handle_wrapper->get(), signals, MOJO_DEADLINE_INDEFINITE, 38 waiting_callback->handle_watcher_.Start(
37 base::Bind(&WaitingCallback::OnHandleReady, 39 handle_wrapper->get(), signals, MOJO_DEADLINE_INDEFINITE,
38 base::Unretained(waiting_callback.get()))); 40 base::Bind(&WaitingCallback::OnHandleReady,
41 base::Unretained(waiting_callback.get())));
42 } else {
43 waiting_callback->watcher_.Start(
44 handle_wrapper->get(), signals,
45 base::Bind(&WaitingCallback::OnHandleReady,
46 base::Unretained(waiting_callback.get())));
47 }
39 return waiting_callback; 48 return waiting_callback;
40 } 49 }
41 50
42 void WaitingCallback::Cancel() { 51 void WaitingCallback::Cancel() {
43 if (!handle_watcher_.is_watching()) 52 if (!handle_watcher_.is_watching() && !watcher_.IsWatching())
44 return; 53 return;
45 54
46 RemoveHandleCloseObserver(); 55 if (handle_watcher_.is_watching()) {
47 handle_watcher_.Stop(); 56 DCHECK(one_shot_);
57 DCHECK(!watcher_.IsWatching());
58 RemoveHandleCloseObserver();
59 handle_watcher_.Stop();
60 } else {
61 DCHECK(!one_shot_);
62 DCHECK(watcher_.IsWatching());
63 watcher_.Cancel();
64 handle_wrapper_ = nullptr;
65 }
48 } 66 }
49 67
50 WaitingCallback::WaitingCallback(v8::Isolate* isolate, 68 WaitingCallback::WaitingCallback(v8::Isolate* isolate,
51 v8::Handle<v8::Function> callback, 69 v8::Handle<v8::Function> callback,
52 gin::Handle<HandleWrapper> handle_wrapper) 70 gin::Handle<HandleWrapper> handle_wrapper,
53 : handle_wrapper_(handle_wrapper.get()), 71 bool one_shot)
72 : one_shot_(one_shot),
73 handle_wrapper_(handle_wrapper.get()),
54 weak_factory_(this) { 74 weak_factory_(this) {
55 handle_wrapper_->AddCloseObserver(this); 75 if (one_shot_) {
76 // We need to manually signal cancellation if the handle is closed while
77 // waiting in one-shot mode. When using non-one-shot mode this cancellation
78 // behavior is already provided for us.
79 handle_wrapper_->AddCloseObserver(this);
80 }
81
56 v8::Handle<v8::Context> context = isolate->GetCurrentContext(); 82 v8::Handle<v8::Context> context = isolate->GetCurrentContext();
57 runner_ = gin::PerContextData::From(context)->runner()->GetWeakPtr(); 83 runner_ = gin::PerContextData::From(context)->runner()->GetWeakPtr();
58 GetWrapper(isolate) 84 GetWrapper(isolate)
59 ->SetPrivate(context, GetHiddenPropertyName(isolate), callback) 85 ->SetPrivate(context, GetHiddenPropertyName(isolate), callback)
60 .FromJust(); 86 .FromJust();
61 } 87 }
62 88
63 WaitingCallback::~WaitingCallback() { 89 WaitingCallback::~WaitingCallback() {
64 Cancel(); 90 Cancel();
65 } 91 }
66 92
67 void WaitingCallback::RemoveHandleCloseObserver() { 93 void WaitingCallback::RemoveHandleCloseObserver() {
94 DCHECK(one_shot_);
68 handle_wrapper_->RemoveCloseObserver(this); 95 handle_wrapper_->RemoveCloseObserver(this);
69 handle_wrapper_ = nullptr; 96 handle_wrapper_ = nullptr;
70 } 97 }
71 98
72 void WaitingCallback::OnHandleReady(MojoResult result) { 99 void WaitingCallback::OnHandleReady(MojoResult result) {
73 RemoveHandleCloseObserver(); 100 if (one_shot_)
101 RemoveHandleCloseObserver();
102
74 CallCallback(result); 103 CallCallback(result);
75 } 104 }
76 105
77 void WaitingCallback::CallCallback(MojoResult result) { 106 void WaitingCallback::CallCallback(MojoResult result) {
78 DCHECK(!handle_watcher_.is_watching()); 107 DCHECK(
79 DCHECK(!handle_wrapper_); 108 // Either this is a one-shot callback and its HandleWatcher should have been
109 // stopped already...
110 (one_shot_ && !handle_wrapper_ && !handle_watcher_.is_watching()) ||
111 // Or it's not a one-shot callback and the Watcher is either still active or
112 // was implicitly cancelled and this is a notification of that fact.
113 (!one_shot_ && handle_wrapper_ &&
114 (watcher_.IsWatching() || result == MOJO_RESULT_CANCELLED)));
80 115
81 if (!runner_) 116 if (!runner_)
82 return; 117 return;
83 118
84 gin::Runner::Scope scope(runner_.get()); 119 gin::Runner::Scope scope(runner_.get());
85 v8::Isolate* isolate = runner_->GetContextHolder()->isolate(); 120 v8::Isolate* isolate = runner_->GetContextHolder()->isolate();
86 121
87 v8::Handle<v8::Value> hidden_value = 122 v8::Handle<v8::Value> hidden_value =
88 GetWrapper(isolate) 123 GetWrapper(isolate)
89 ->GetPrivate(runner_->GetContextHolder()->context(), 124 ->GetPrivate(runner_->GetContextHolder()->context(),
90 GetHiddenPropertyName(isolate)) 125 GetHiddenPropertyName(isolate))
91 .ToLocalChecked(); 126 .ToLocalChecked();
92 v8::Handle<v8::Function> callback; 127 v8::Handle<v8::Function> callback;
93 CHECK(gin::ConvertFromV8(isolate, hidden_value, &callback)); 128 CHECK(gin::ConvertFromV8(isolate, hidden_value, &callback));
94 129
95 v8::Handle<v8::Value> args[] = { gin::ConvertToV8(isolate, result) }; 130 v8::Handle<v8::Value> args[] = { gin::ConvertToV8(isolate, result) };
96 runner_->Call(callback, runner_->global(), 1, args); 131 runner_->Call(callback, runner_->global(), 1, args);
97 } 132 }
98 133
99 void WaitingCallback::OnWillCloseHandle() { 134 void WaitingCallback::OnWillCloseHandle() {
135 DCHECK(one_shot_);
136
100 handle_watcher_.Stop(); 137 handle_watcher_.Stop();
101 138
102 // This may be called from GC, so we can't execute Javascript now, call 139 // This may be called from GC, so we can't execute Javascript now, call
103 // RemoveHandleCloseObserver explicitly, and CallCallback asynchronously. 140 // RemoveHandleCloseObserver explicitly, and CallCallback asynchronously.
104 RemoveHandleCloseObserver(); 141 RemoveHandleCloseObserver();
105 base::MessageLoop::current()->PostTask( 142 base::MessageLoop::current()->PostTask(
106 FROM_HERE, 143 FROM_HERE,
107 base::Bind(&WaitingCallback::CallCallback, weak_factory_.GetWeakPtr(), 144 base::Bind(&WaitingCallback::CallCallback, weak_factory_.GetWeakPtr(),
108 MOJO_RESULT_INVALID_ARGUMENT)); 145 MOJO_RESULT_CANCELLED));
109 } 146 }
110 147
111 } // namespace js 148 } // namespace js
112 } // namespace edk 149 } // namespace edk
113 } // namespace mojo 150 } // namespace mojo
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698