Flutter Engine
 
Loading...
Searching...
No Matches
dart_message_handler.cc
Go to the documentation of this file.
1// Copyright 2013 The Flutter 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
6
7#include "third_party/dart/runtime/include/dart_api.h"
8#include "third_party/dart/runtime/include/dart_native_api.h"
9#include "third_party/dart/runtime/include/dart_tools_api.h"
10#include "tonic/common/macros.h"
11#include "tonic/dart_state.h"
13
14namespace tonic {
15
17 : handled_first_message_(false),
18 isolate_exited_(false),
19 isolate_had_uncaught_exception_error_(false),
20 isolate_had_fatal_error_(false),
21 isolate_last_error_(kNoError),
22 task_dispatcher_(nullptr) {}
23
27
29 // Only can be called once.
30 TONIC_CHECK(!task_dispatcher_ && dispatcher);
31 task_dispatcher_ = dispatcher;
32 Dart_SetMessageNotifyCallback(MessageNotifyCallback);
33}
34
37
38 // Schedule a task to run on the message loop thread.
39 auto weak_dart_state = dart_state->GetWeakPtr();
40 task_dispatcher_([weak_dart_state]() {
41 if (auto dart_state = weak_dart_state.lock()) {
42 if (!dart_state->IsShuttingDown()) {
43 dart_state->message_handler().OnHandleMessage(dart_state.get());
44 }
45 }
46 });
47}
48
49void DartMessageHandler::UnhandledError(Dart_Handle error) {
50 TONIC_DCHECK(Dart_CurrentIsolate());
51 TONIC_DCHECK(Dart_IsError(error));
52
53 isolate_last_error_ = GetErrorHandleType(error);
54 // Remember that we had an uncaught exception error.
55 isolate_had_uncaught_exception_error_ = true;
56 if (Dart_IsFatalError(error)) {
57 isolate_had_fatal_error_ = true;
58 // Stop handling messages.
59 Dart_SetMessageNotifyCallback(nullptr);
60 // Shut down the isolate.
61 Dart_ShutdownIsolate();
62 }
63}
64
65void DartMessageHandler::OnHandleMessage(DartState* dart_state) {
66 if (isolate_had_fatal_error_) {
67 // Don't handle any more messages.
68 return;
69 }
70
71 DartIsolateScope scope(dart_state->isolate());
72 DartApiScope dart_api_scope;
73 Dart_Handle result = Dart_Null();
74 bool error = false;
75
76 // On the first message, check if we should pause on isolate start.
77 if (!handled_first_message()) {
78 set_handled_first_message(true);
79 if (Dart_ShouldPauseOnStart()) {
80 // Mark that we are paused on isolate start.
81 Dart_SetPausedOnStart(true);
82 }
83 }
84
85 if (Dart_IsPausedOnStart()) {
86 // We are paused on isolate start. Only handle service messages until we are
87 // requested to resume.
88 if (Dart_HasServiceMessages()) {
89 bool resume = Dart_HandleServiceMessages();
90 if (!resume) {
91 return;
92 }
93 Dart_SetPausedOnStart(false);
94 // We've resumed, handle normal messages that are in the queue.
95 result = Dart_HandleMessage();
96 error = CheckAndHandleError(result);
97 dart_state->MessageEpilogue(result);
98 if (!Dart_CurrentIsolate()) {
99 isolate_exited_ = true;
100 return;
101 }
102 }
103 } else if (Dart_IsPausedOnExit()) {
104 // We are paused on isolate exit. Only handle service messages until we are
105 // requested to resume.
106 if (Dart_HasServiceMessages()) {
107 bool resume = Dart_HandleServiceMessages();
108 if (!resume) {
109 return;
110 }
111 Dart_SetPausedOnExit(false);
112 }
113 } else {
114 // We are processing messages normally.
115 result = Dart_HandleMessage();
116 // If the Dart program has set a return code, then it is intending to shut
117 // down by way of a fatal error, and so there is no need to emit a log
118 // message.
119 if (dart_state->has_set_return_code() && Dart_IsError(result) &&
120 Dart_IsFatalError(result)) {
121 error = true;
122 } else {
123 error = CheckAndHandleError(result);
124 }
125 dart_state->MessageEpilogue(result);
126 if (!Dart_CurrentIsolate()) {
127 isolate_exited_ = true;
128 return;
129 }
130 }
131
132 if (error) {
133 UnhandledError(result);
134 } else if (!Dart_HasLivePorts()) {
135 // The isolate has no live ports and would like to exit.
136 if (!Dart_IsPausedOnExit() && Dart_ShouldPauseOnExit()) {
137 // Mark that we are paused on exit.
138 Dart_SetPausedOnExit(true);
139 } else {
140 isolate_exited_ = true;
141 }
142 }
143}
144
145void DartMessageHandler::MessageNotifyCallback(Dart_Isolate dest_isolate) {
146 auto dart_state = DartState::From(dest_isolate);
147 TONIC_CHECK(dart_state);
148 dart_state->message_handler().OnMessage(dart_state);
149}
150
151} // namespace tonic
std::function< void(std::function< void(void)>)> TaskDispatcher
void OnMessage(DartState *dart_state)
void Initialize(TaskDispatcher dispatcher)
Dart_Isolate isolate()
Definition dart_state.h:51
DartMessageHandler & message_handler()
Definition dart_state.h:61
void MessageEpilogue(Dart_Handle message_result)
Definition dart_state.h:64
bool has_set_return_code() const
Definition dart_state.h:71
std::weak_ptr< DartState > GetWeakPtr()
Definition dart_state.cc:62
const uint8_t uint32_t uint32_t GError ** error
DartErrorHandleType GetErrorHandleType(Dart_Handle handle)
Definition dart_error.cc:56
@ kNoError
Definition dart_error.h:68
bool CheckAndHandleError(Dart_Handle handle)
Definition dart_error.cc:33
#define TONIC_CHECK(condition)
Definition macros.h:23
#define TONIC_DCHECK
Definition macros.h:32