Flutter Engine
dart_vm_initializer.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 
5 #include "flutter/runtime/dart_vm_initializer.h"
6 
7 #include <atomic>
8 
9 #include "flutter/fml/logging.h"
10 #include "flutter/fml/synchronization/shared_mutex.h"
11 #include "flutter/fml/trace_event.h"
12 
13 // Tracks whether Dart has been initialized and if it is safe to call Dart
14 // APIs.
15 static std::atomic<bool> gDartInitialized;
16 
17 void DartVMInitializer::Initialize(Dart_InitializeParams* params) {
19 
20  char* error = Dart_Initialize(params);
21  if (error) {
22  FML_LOG(FATAL) << "Error while initializing the Dart VM: " << error;
23  ::free(error);
24  } else {
25  gDartInitialized = true;
26  }
27 
28  fml::tracing::TraceSetTimelineEventHandler(LogDartTimelineEvent);
29 }
30 
33 
34  // Dart_TimelineEvent is unsafe during a concurrent call to Dart_Cleanup
35  // because Dart_Cleanup will destroy the timeline recorder. Clear the
36  // initialized flag so that future calls to LogDartTimelineEvent will not
37  // call Dart_TimelineEvent.
38  //
39  // Note that this is inherently racy. If a thread sees that gDartInitialized
40  // is set and proceeds to call Dart_TimelineEvent shortly before another
41  // thread calls Dart_Cleanup, then the Dart_TimelineEvent call may crash
42  // if Dart_Cleanup deletes the timeline before Dart_TimelineEvent completes.
43  // In practice this is unlikely because Dart_Cleanup does significant other
44  // work before deleting the timeline.
45  //
46  // The engine can not safely guard Dart_Cleanup and LogDartTimelineEvent with
47  // a lock due to the risk of deadlocks. Dart_Cleanup waits for various
48  // Dart-owned threads to shut down. If one of those threads invokes an engine
49  // callback that calls LogDartTimelineEvent while the Dart_Cleanup thread owns
50  // the lock, then Dart_Cleanup would deadlock.
51  gDartInitialized = false;
52 
53  char* error = Dart_Cleanup();
54  if (error) {
55  FML_LOG(FATAL) << "Error while cleaning up the Dart VM: " << error;
56  ::free(error);
57  }
58 }
59 
60 void DartVMInitializer::LogDartTimelineEvent(const char* label,
61  int64_t timestamp0,
62  int64_t timestamp1_or_async_id,
63  Dart_Timeline_Event_Type type,
64  intptr_t argument_count,
65  const char** argument_names,
66  const char** argument_values) {
67  if (gDartInitialized) {
68  Dart_TimelineEvent(label, timestamp0, timestamp1_or_async_id, type,
69  argument_count, argument_names, argument_values);
70  }
71 }
const uint8_t uint32_t uint32_t GError ** error
#define FML_DCHECK(condition)
Definition: logging.h:86
#define FML_LOG(severity)
Definition: logging.h:65
int argument_count
Definition: fuchsia.cc:52
static void Initialize(Dart_InitializeParams *params)
GdkEventType type
Definition: fl_view.cc:80
void TraceSetTimelineEventHandler(TimelineEventHandler handler)
Definition: trace_event.cc:296
static std::atomic< bool > gDartInitialized