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

Side by Side Diff: tonic/dart_message_handler.cc

Issue 1688793002: Fix shutdown race when running Dart on the message loop (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: Created 4 years, 10 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
« no previous file with comments | « tonic/dart_message_handler.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 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 "tonic/dart_message_handler.h" 5 #include "tonic/dart_message_handler.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "dart/runtime/include/dart_api.h" 8 #include "dart/runtime/include/dart_api.h"
9 #include "dart/runtime/include/dart_native_api.h" 9 #include "dart/runtime/include/dart_native_api.h"
10 #include "dart/runtime/include/dart_tools_api.h" 10 #include "dart/runtime/include/dart_tools_api.h"
11 #include "tonic/dart_error.h" 11 #include "tonic/dart_error.h"
12 #include "tonic/dart_state.h" 12 #include "tonic/dart_state.h"
13 13
14 namespace tonic { 14 namespace tonic {
15 15
16 DartMessageHandler::DartMessageHandler() 16 DartMessageHandler::DartMessageHandler()
17 : handled_first_message_(false), 17 : handled_first_message_(false),
18 quit_message_loop_when_isolate_exits_(true),
19 isolate_exited_(false),
20 isolate_had_uncaught_exception_error_(false),
18 task_runner_(nullptr) { 21 task_runner_(nullptr) {
19 } 22 }
20 23
21 DartMessageHandler::~DartMessageHandler() { 24 DartMessageHandler::~DartMessageHandler() {
22 task_runner_ = nullptr; 25 task_runner_ = nullptr;
23 } 26 }
24 27
25 void DartMessageHandler::Initialize( 28 void DartMessageHandler::Initialize(
26 const scoped_refptr<base::SingleThreadTaskRunner>& runner) { 29 const scoped_refptr<base::SingleThreadTaskRunner>& runner) {
27 // Only can be called once. 30 // Only can be called once.
28 CHECK(!task_runner_); 31 CHECK(!task_runner_);
29 task_runner_ = runner; 32 task_runner_ = runner;
30 CHECK(task_runner_); 33 CHECK(task_runner_);
31 Dart_SetMessageNotifyCallback(MessageNotifyCallback); 34 Dart_SetMessageNotifyCallback(MessageNotifyCallback);
32 } 35 }
33 36
34 void DartMessageHandler::OnMessage(DartState* dart_state) { 37 void DartMessageHandler::OnMessage(DartState* dart_state) {
35 auto task_runner = dart_state->message_handler().task_runner(); 38 auto task_runner = dart_state->message_handler().task_runner();
36 39
37 // Schedule a task to run on the message loop thread. 40 // Schedule a task to run on the message loop thread.
38 task_runner->PostTask(FROM_HERE, 41 task_runner->PostTask(FROM_HERE,
39 base::Bind(&HandleMessage, dart_state->GetWeakPtr())); 42 base::Bind(&HandleMessage, dart_state->GetWeakPtr()));
40 } 43 }
41 44
42 void DartMessageHandler::OnHandleMessage(DartState* dart_state) { 45 void DartMessageHandler::OnHandleMessage(DartState* dart_state) {
43 DartIsolateScope scope(dart_state->isolate()); 46 DartIsolateScope scope(dart_state->isolate());
44 DartApiScope dart_api_scope; 47 DartApiScope dart_api_scope;
45 48
49 bool error = false;
50
46 // On the first message, check if we should pause on isolate start. 51 // On the first message, check if we should pause on isolate start.
47 if (!handled_first_message()) { 52 if (!handled_first_message()) {
48 set_handled_first_message(true); 53 set_handled_first_message(true);
49 if (Dart_ShouldPauseOnStart()) { 54 if (Dart_ShouldPauseOnStart()) {
50 // Mark that we are paused on isolate start. 55 // Mark that we are paused on isolate start.
51 Dart_SetPausedOnStart(true); 56 Dart_SetPausedOnStart(true);
52 } 57 }
53 } 58 }
54 59
55 if (Dart_IsPausedOnStart()) { 60 if (Dart_IsPausedOnStart()) {
56 // We are paused on isolate start. Only handle service messages until we are 61 // We are paused on isolate start. Only handle service messages until we are
57 // requested to resume. 62 // requested to resume.
58 if (Dart_HasServiceMessages()) { 63 if (Dart_HasServiceMessages()) {
59 bool resume = Dart_HandleServiceMessages(); 64 bool resume = Dart_HandleServiceMessages();
60 if (!resume) { 65 if (!resume) {
61 return; 66 return;
62 } 67 }
63 Dart_SetPausedOnStart(false); 68 Dart_SetPausedOnStart(false);
64 // We've resumed, handle *all* normal messages that are in the queue. 69 // We've resumed, handle *all* normal messages that are in the queue.
65 LogIfError(Dart_HandleMessages()); 70 error = LogIfError(Dart_HandleMessages());
66 } 71 }
67 } else if (Dart_IsPausedOnExit()) { 72 } else if (Dart_IsPausedOnExit()) {
68 // We are paused on isolate exit. Only handle service messages until we are 73 // We are paused on isolate exit. Only handle service messages until we are
69 // requested to resume. 74 // requested to resume.
70 if (Dart_HasServiceMessages()) { 75 if (Dart_HasServiceMessages()) {
71 bool resume = Dart_HandleServiceMessages(); 76 bool resume = Dart_HandleServiceMessages();
72 if (!resume) { 77 if (!resume) {
73 return; 78 return;
74 } 79 }
75 Dart_SetPausedOnExit(false); 80 Dart_SetPausedOnExit(false);
76 } 81 }
77 } else { 82 } else {
78 // We are processing messages normally. 83 // We are processing messages normally.
79 LogIfError(Dart_HandleMessage()); 84 error = LogIfError(Dart_HandleMessage());
80 } 85 }
81 86
82 if (!Dart_HasLivePorts()) { 87 if (error) {
88 // Remember that we had an uncaught exception error.
89 isolate_had_uncaught_exception_error_ = true;
90 }
91
92 if (error || !Dart_HasLivePorts()) {
83 // The isolate has no live ports and would like to exit. 93 // The isolate has no live ports and would like to exit.
84 if (Dart_ShouldPauseOnExit()) { 94 if (Dart_ShouldPauseOnExit()) {
85 // Mark that we are paused on exit. 95 // Mark that we are paused on exit.
86 Dart_SetPausedOnExit(true); 96 Dart_SetPausedOnExit(true);
87 } else { 97 } else {
88 // Quit. 98 isolate_exited_ = true;
89 base::MessageLoop::current()->QuitWhenIdle(); 99 if (quit_message_loop_when_isolate_exits()) {
100 // Quit.
101 base::MessageLoop::current()->QuitWhenIdle();
102 }
90 } 103 }
91 } 104 }
92 } 105 }
93 106
94 void DartMessageHandler::MessageNotifyCallback(Dart_Isolate dest_isolate) { 107 void DartMessageHandler::MessageNotifyCallback(Dart_Isolate dest_isolate) {
95 auto dart_state = DartState::From(dest_isolate); 108 auto dart_state = DartState::From(dest_isolate);
96 CHECK(dart_state); 109 CHECK(dart_state);
97 dart_state->message_handler().OnMessage(dart_state); 110 dart_state->message_handler().OnMessage(dart_state);
98 } 111 }
99 112
100 void DartMessageHandler::HandleMessage( 113 void DartMessageHandler::HandleMessage(
101 base::WeakPtr<DartState> dart_state) { 114 base::WeakPtr<DartState> dart_state) {
102 if (!dart_state) 115 if (!dart_state)
103 return; 116 return;
104 dart_state->message_handler().OnHandleMessage(dart_state.get()); 117 dart_state->message_handler().OnHandleMessage(dart_state.get());
105 } 118 }
106 119
107 } // namespace tonic 120 } // namespace tonic
OLDNEW
« no previous file with comments | « tonic/dart_message_handler.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698