Flutter Engine
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 
14 namespace 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 
25  task_dispatcher_ = nullptr;
26 }
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  dart_state->message_handler().OnHandleMessage(dart_state.get());
43  }
44  });
45 }
46 
48  TONIC_DCHECK(Dart_CurrentIsolate());
49  TONIC_DCHECK(Dart_IsError(error));
50 
52  // Remember that we had an uncaught exception error.
54  if (Dart_IsFatalError(error)) {
56  // Stop handling messages.
57  Dart_SetMessageNotifyCallback(nullptr);
58  // Shut down the isolate.
59  Dart_ShutdownIsolate();
60  }
61 }
62 
65  // Don't handle any more messages.
66  return;
67  }
68 
69  DartIsolateScope scope(dart_state->isolate());
70  DartApiScope dart_api_scope;
71  Dart_Handle result = Dart_Null();
72  bool error = false;
73 
74  // On the first message, check if we should pause on isolate start.
75  if (!handled_first_message()) {
77  if (Dart_ShouldPauseOnStart()) {
78  // Mark that we are paused on isolate start.
79  Dart_SetPausedOnStart(true);
80  }
81  }
82 
83  if (Dart_IsPausedOnStart()) {
84  // We are paused on isolate start. Only handle service messages until we are
85  // requested to resume.
86  if (Dart_HasServiceMessages()) {
87  bool resume = Dart_HandleServiceMessages();
88  if (!resume) {
89  return;
90  }
91  Dart_SetPausedOnStart(false);
92  // We've resumed, handle normal messages that are in the queue.
93  result = Dart_HandleMessage();
94  error = LogIfError(result);
95  dart_state->MessageEpilogue(result);
96  if (!Dart_CurrentIsolate()) {
97  isolate_exited_ = true;
98  return;
99  }
100  }
101  } else if (Dart_IsPausedOnExit()) {
102  // We are paused on isolate exit. Only handle service messages until we are
103  // requested to resume.
104  if (Dart_HasServiceMessages()) {
105  bool resume = Dart_HandleServiceMessages();
106  if (!resume) {
107  return;
108  }
109  Dart_SetPausedOnExit(false);
110  }
111  } else {
112  // We are processing messages normally.
113  result = Dart_HandleMessage();
114  // If the Dart program has set a return code, then it is intending to shut
115  // down by way of a fatal error, and so there is no need to emit a log
116  // message.
117  if (dart_state->has_set_return_code() && Dart_IsError(result) &&
118  Dart_IsFatalError(result)) {
119  error = true;
120  } else {
121  error = LogIfError(result);
122  }
123  dart_state->MessageEpilogue(result);
124  if (!Dart_CurrentIsolate()) {
125  isolate_exited_ = true;
126  return;
127  }
128  }
129 
130  if (error) {
131  UnhandledError(result);
132  } else if (!Dart_HasLivePorts()) {
133  // The isolate has no live ports and would like to exit.
134  if (!Dart_IsPausedOnExit() && Dart_ShouldPauseOnExit()) {
135  // Mark that we are paused on exit.
136  Dart_SetPausedOnExit(true);
137  } else {
138  isolate_exited_ = true;
139  }
140  }
141 }
142 
143 void DartMessageHandler::MessageNotifyCallback(Dart_Isolate dest_isolate) {
144  auto dart_state = DartState::From(dest_isolate);
145  TONIC_CHECK(dart_state);
146  dart_state->message_handler().OnMessage(dart_state);
147 }
148 
149 } // namespace tonic
bool has_set_return_code() const
Definition: dart_state.h:69
Dart_Isolate isolate()
Definition: dart_state.h:49
void OnHandleMessage(DartState *dart_state)
#define TONIC_DCHECK
Definition: macros.h:32
FlMethodResponse GError ** error
static DartState * From(Dart_Isolate isolate)
Definition: dart_state.cc:49
void OnMessage(DartState *dart_state)
DartErrorHandleType GetErrorHandleType(Dart_Handle handle)
Definition: dart_error.cc:34
std::function< void(std::function< void(void)>)> TaskDispatcher
DartErrorHandleType isolate_last_error_
std::weak_ptr< DartState > GetWeakPtr()
Definition: dart_state.cc:61
#define TONIC_CHECK(condition)
Definition: macros.h:23
void Initialize(TaskDispatcher dispatcher)
void MessageEpilogue(Dart_Handle message_result)
Definition: dart_state.h:62
void set_handled_first_message(bool handled_first_message)
bool LogIfError(Dart_Handle handle)
Definition: dart_error.cc:15
DartMessageHandler & message_handler()
Definition: dart_state.h:59
void UnhandledError(Dart_Handle error)