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#ifndef FLUTTER_SHELL_COMMON_ISOLATE_CONFIGURATION_H_
6#define FLUTTER_SHELL_COMMON_ISOLATE_CONFIGURATION_H_
7
8#include <future>
9#include <memory>
10#include <string>
11
12#include "flutter/assets/asset_manager.h"
13#include "flutter/assets/asset_resolver.h"
14#include "flutter/common/settings.h"
15#include "flutter/fml/macros.h"
16#include "flutter/fml/mapping.h"
17#include "flutter/fml/memory/weak_ptr.h"
18#include "flutter/runtime/dart_isolate.h"
19
20namespace flutter {
21
22//------------------------------------------------------------------------------
23/// @brief An isolate configuration is a collection of snapshots and asset
24/// managers that the engine will use to configure the isolate
25/// before invoking its root entrypoint. The set of snapshots must
26/// be sufficient for the engine to move the isolate from the
27/// |DartIsolate::Phase::LibrariesSetup| phase to the
28/// |DartIsolate::Phase::Ready| phase. Note that the isolate
29/// configuration will not be collected till the isolate tied to the
30/// configuration as well as any and all child isolates of that
31/// isolate are collected. The engine may ask the configuration to
32/// prepare multiple isolates. All subclasses of this class must be
33/// thread safe as the configuration may be created, collected and
34/// used on multiple threads. Usually these threads are engine or VM
35/// managed so care must be taken to ensure that subclasses do not
36/// reference any thread local state.
37///
38class IsolateConfiguration {
39 public:
40 //----------------------------------------------------------------------------
41 /// @brief Attempts to infer the isolate configuration from the
42 /// `Settings` object. If the VM is configured for AOT mode,
43 /// snapshot resolution is attempted with predefined symbols
44 /// present in the currently loaded process. In JIT mode, Dart
45 /// kernel file resolution is attempted in the assets directory.
46 /// If an IO worker is specified, snapshot resolution may be
47 /// attempted on the serial worker task runner. The worker task
48 /// runner thread must remain valid and running till after the
49 /// shell associated with the engine used to launch the isolate
50 /// for which this run configuration is used is collected.
51 ///
52 /// @param[in] settings The settings
53 /// @param[in] asset_manager The asset manager
54 /// @param[in] io_worker An optional IO worker. Specify `nullptr` is a
55 /// worker should not be used or one is not
56 /// available.
57 ///
58 /// @return An isolate configuration if one can be inferred from the
59 /// settings. If not, returns `nullptr`.
60 ///
61 static std::unique_ptr<IsolateConfiguration> InferFromSettings(
62 const Settings& settings,
63 std::shared_ptr<AssetManager> asset_manager,
64 fml::RefPtr<fml::TaskRunner> io_worker);
65
66 //----------------------------------------------------------------------------
67 /// @brief Creates an AOT isolate configuration using snapshot symbols
68 /// present in the currently loaded process. These symbols need to
69 /// be given to the Dart VM on bootstrap and hence have already
70 /// been resolved.
71 ///
72 /// @return An AOT isolate configuration.
73 ///
74 static std::unique_ptr<IsolateConfiguration> CreateForAppSnapshot();
75
76 //----------------------------------------------------------------------------
77 /// @brief Creates a JIT isolate configuration using a list of futures to
78 /// snapshots defining the ready isolate state. In environments
79 /// where snapshot resolution is extremely expensive, embedders
80 /// attempt to resolve snapshots on worker thread(s) and return
81 /// the future of the promise of snapshot resolution to this
82 /// method. That way, snapshot resolution begins well before
83 /// isolate launch is attempted by the engine.
84 ///
85 /// @param[in] kernel_pieces The list of futures to Dart kernel snapshots.
86 ///
87 /// @return A JIT isolate configuration.
88 ///
89 static std::unique_ptr<IsolateConfiguration> CreateForKernelList(
90 std::vector<std::future<std::unique_ptr<const fml::Mapping>>>
91 kernel_pieces);
92
93 //----------------------------------------------------------------------------
94 /// @brief Creates a JIT isolate configuration using the specified
95 /// snapshot. This is a convenience method for the
96 /// `CreateForKernelList` method that takes a list of futures to
97 /// Dart kernel snapshots.
98 ///
99 /// @see CreateForKernelList()
100 ///
101 /// @param[in] kernel The kernel snapshot.
102 ///
103 /// @return A JIT isolate configuration.
104 ///
105 static std::unique_ptr<IsolateConfiguration> CreateForKernel(
106 std::unique_ptr<const fml::Mapping> kernel);
107
108 //----------------------------------------------------------------------------
109 /// @brief Creates a JIT isolate configuration using the specified
110 /// snapshots. This is a convenience method for the
111 /// `CreateForKernelList` method that takes a list of futures to
112 /// Dart kernel snapshots.
113 ///
114 /// @see CreateForKernelList()
115 ///
116 /// @param[in] kernel_pieces The kernel pieces
117 ///
118 /// @return { description_of_the_return_value }
119 ///
120 static std::unique_ptr<IsolateConfiguration> CreateForKernelList(
121 std::vector<std::unique_ptr<const fml::Mapping>> kernel_pieces);
122
123 //----------------------------------------------------------------------------
124 /// @brief Create an isolate configuration. This has no threading
125 /// restrictions.
126 ///
127 IsolateConfiguration();
128
129 //----------------------------------------------------------------------------
130 /// @brief Destroys an isolate configuration. This has no threading
131 /// restrictions and may be collection of configurations may occur
132 /// on any thread (and usually happens on an internal VM managed
133 /// thread pool thread).
134 ///
135 virtual ~IsolateConfiguration();
136
137 //----------------------------------------------------------------------------
138 /// @brief When an isolate is created and sufficiently initialized to
139 /// move it into the `DartIsolate::Phase::LibrariesSetup` phase,
140 /// this method is invoked on the isolate to then move the isolate
141 /// into the `DartIsolate::Phase::Ready` phase. Then isolate's
142 /// main entrypoint is then invoked to move it into the
143 /// `DartIsolate::Phase::Running` phase. This method will be
144 /// called each time the root isolate is launched (which may be
145 /// multiple times in cold-restart scenarios) as well as one each
146 /// for any child isolates referenced by that isolate.
147 ///
148 /// @param isolate The isolate which is already in the
149 /// `DartIsolate::Phase::LibrariesSetup` phase.
150 ///
151 /// @return Returns true if the isolate could be configured. Unless this
152 /// returns true, the engine will not move the isolate to the
153 /// `DartIsolate::Phase::Ready` phase for subsequent run.
154 ///
155 bool PrepareIsolate(DartIsolate& isolate);
156
157 protected:
158 virtual bool DoPrepareIsolate(DartIsolate& isolate) = 0;
159
160 private:
161 FML_DISALLOW_COPY_AND_ASSIGN(IsolateConfiguration);
162};
163
164} // namespace flutter
165
166#endif // FLUTTER_SHELL_COMMON_ISOLATE_CONFIGURATION_H_
167