Flutter Engine
dart_microtask_queue.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 
8 #include "tonic/dart_state.h"
10 
11 #ifdef OS_IOS
12 #include <pthread.h>
13 #endif // OS_IOS
14 
15 namespace tonic {
16 namespace {
17 
18 #ifdef OS_IOS
19 // iOS doesn't support the thread_local keyword.
20 
21 pthread_key_t g_queue_key;
22 pthread_once_t g_queue_key_once = PTHREAD_ONCE_INIT;
23 
24 void MakeKey() {
25  pthread_key_create(&g_queue_key, nullptr);
26 }
27 
28 void SetQueue(DartMicrotaskQueue* queue) {
29  pthread_once(&g_queue_key_once, MakeKey);
30  pthread_setspecific(g_queue_key, queue);
31 }
32 
33 DartMicrotaskQueue* GetQueue() {
34  return static_cast<tonic::DartMicrotaskQueue*>(
35  pthread_getspecific(g_queue_key));
36 }
37 
38 #else
39 
40 thread_local DartMicrotaskQueue* g_queue = nullptr;
41 
42 void SetQueue(DartMicrotaskQueue* queue) {
43  g_queue = queue;
44 }
45 
46 DartMicrotaskQueue* GetQueue() {
47  return g_queue;
48 }
49 
50 #endif
51 
52 } // namespace
53 
55 
57 
59  SetQueue(new DartMicrotaskQueue());
60 }
61 
63  return GetQueue();
64 }
65 
66 void DartMicrotaskQueue::ScheduleMicrotask(Dart_Handle callback) {
67  queue_.emplace_back(DartState::Current(), callback);
68 }
69 
71  while (!queue_.empty()) {
72  MicrotaskQueue local;
73  std::swap(queue_, local);
74  for (const auto& callback : local) {
75  if (auto dart_state = callback.dart_state().lock()) {
76  DartState::Scope dart_scope(dart_state.get());
77  Dart_Handle result = Dart_InvokeClosure(callback.value(), 0, nullptr);
78  // If the Dart program has set a return code, then it is intending to
79  // shut down by way of a fatal error, and so there is no need to emit a
80  // log message.
81  if (!dart_state->has_set_return_code() || !Dart_IsError(result) ||
82  !Dart_IsFatalError(result)) {
83  LogIfError(result);
84  }
86  if (error != kNoError) {
87  last_error_ = error;
88  }
89  dart_state->MessageEpilogue(result);
90  if (!Dart_CurrentIsolate())
91  return;
92  }
93  }
94  }
95 }
96 
99  SetQueue(nullptr);
100  delete this;
101 }
102 
104  return last_error_;
105 }
106 
107 } // namespace tonic
static DartMicrotaskQueue * GetForCurrentThread()
#define TONIC_DCHECK
Definition: macros.h:32
FlMethodResponse GError ** error
static DartState * Current()
Definition: dart_state.cc:55
void swap(scoped_nsprotocol< C > &p1, scoped_nsprotocol< C > &p2)
DartErrorHandleType GetErrorHandleType(Dart_Handle handle)
Definition: dart_error.cc:34
DartErrorHandleType
Definition: dart_error.h:18
void ScheduleMicrotask(Dart_Handle callback)
bool LogIfError(Dart_Handle handle)
Definition: dart_error.cc:15
DartErrorHandleType GetLastError()