| 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_RUNTIME_ISOLATE_CONFIGURATION_H_ |
| 6 | #define FLUTTER_SHELL_RUNTIME_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 | |
| 20 | namespace 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 | /// |
| 38 | class 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 optional asset manager. This is used when |
| 54 | /// using the legacy settings fields that specify |
| 55 | /// the asset by name instead of a mappings |
| 56 | /// callback. |
| 57 | /// @param[in] io_worker An optional IO worker. Specify `nullptr` if a |
| 58 | /// worker should not be used or one is not |
| 59 | /// available. |
| 60 | /// |
| 61 | /// @return An isolate configuration if one can be inferred from the |
| 62 | /// settings. If not, returns `nullptr`. |
| 63 | /// |
| 64 | [[nodiscard]] static std::unique_ptr<IsolateConfiguration> InferFromSettings( |
| 65 | const Settings& settings, |
| 66 | const std::shared_ptr<AssetManager>& asset_manager = nullptr, |
| 67 | const fml::RefPtr<fml::TaskRunner>& io_worker = nullptr); |
| 68 | |
| 69 | //---------------------------------------------------------------------------- |
| 70 | /// @brief Creates an AOT isolate configuration using snapshot symbols |
| 71 | /// present in the currently loaded process. These symbols need to |
| 72 | /// be given to the Dart VM on bootstrap and hence have already |
| 73 | /// been resolved. |
| 74 | /// |
| 75 | /// @return An AOT isolate configuration. |
| 76 | /// |
| 77 | static std::unique_ptr<IsolateConfiguration> CreateForAppSnapshot(); |
| 78 | |
| 79 | //---------------------------------------------------------------------------- |
| 80 | /// @brief Creates a JIT isolate configuration using a list of futures to |
| 81 | /// snapshots defining the ready isolate state. In environments |
| 82 | /// where snapshot resolution is extremely expensive, embedders |
| 83 | /// attempt to resolve snapshots on worker thread(s) and return |
| 84 | /// the future of the promise of snapshot resolution to this |
| 85 | /// method. That way, snapshot resolution begins well before |
| 86 | /// isolate launch is attempted by the engine. |
| 87 | /// |
| 88 | /// @param[in] kernel_pieces The list of futures to Dart kernel snapshots. |
| 89 | /// |
| 90 | /// @return A JIT isolate configuration. |
| 91 | /// |
| 92 | static std::unique_ptr<IsolateConfiguration> CreateForKernelList( |
| 93 | std::vector<std::future<std::unique_ptr<const fml::Mapping>>> |
| 94 | kernel_pieces); |
| 95 | |
| 96 | //---------------------------------------------------------------------------- |
| 97 | /// @brief Creates a JIT isolate configuration using the specified |
| 98 | /// snapshot. This is a convenience method for the |
| 99 | /// `CreateForKernelList` method that takes a list of futures to |
| 100 | /// Dart kernel snapshots. |
| 101 | /// |
| 102 | /// @see CreateForKernelList() |
| 103 | /// |
| 104 | /// @param[in] kernel The kernel snapshot. |
| 105 | /// |
| 106 | /// @return A JIT isolate configuration. |
| 107 | /// |
| 108 | static std::unique_ptr<IsolateConfiguration> CreateForKernel( |
| 109 | std::unique_ptr<const fml::Mapping> kernel); |
| 110 | |
| 111 | //---------------------------------------------------------------------------- |
| 112 | /// @brief Creates a JIT isolate configuration using the specified |
| 113 | /// snapshots. This is a convenience method for the |
| 114 | /// `CreateForKernelList` method that takes a list of futures to |
| 115 | /// Dart kernel snapshots. |
| 116 | /// |
| 117 | /// @see CreateForKernelList() |
| 118 | /// |
| 119 | /// @param[in] kernel_pieces The kernel pieces |
| 120 | /// |
| 121 | /// @return { description_of_the_return_value } |
| 122 | /// |
| 123 | static std::unique_ptr<IsolateConfiguration> CreateForKernelList( |
| 124 | std::vector<std::unique_ptr<const fml::Mapping>> kernel_pieces); |
| 125 | |
| 126 | //---------------------------------------------------------------------------- |
| 127 | /// @brief Create an isolate configuration. This has no threading |
| 128 | /// restrictions. |
| 129 | /// |
| 130 | IsolateConfiguration(); |
| 131 | |
| 132 | //---------------------------------------------------------------------------- |
| 133 | /// @brief Destroys an isolate configuration. This has no threading |
| 134 | /// restrictions and may be collection of configurations may occur |
| 135 | /// on any thread (and usually happens on an internal VM managed |
| 136 | /// thread pool thread). |
| 137 | /// |
| 138 | virtual ~IsolateConfiguration(); |
| 139 | |
| 140 | //---------------------------------------------------------------------------- |
| 141 | /// @brief When an isolate is created and sufficiently initialized to |
| 142 | /// move it into the `DartIsolate::Phase::LibrariesSetup` phase, |
| 143 | /// this method is invoked on the isolate to then move the isolate |
| 144 | /// into the `DartIsolate::Phase::Ready` phase. Then isolate's |
| 145 | /// main entrypoint is then invoked to move it into the |
| 146 | /// `DartIsolate::Phase::Running` phase. This method will be |
| 147 | /// called each time the root isolate is launched (which may be |
| 148 | /// multiple times in cold-restart scenarios) as well as one each |
| 149 | /// for any child isolates referenced by that isolate. |
| 150 | /// |
| 151 | /// @param isolate The isolate which is already in the |
| 152 | /// `DartIsolate::Phase::LibrariesSetup` phase. |
| 153 | /// |
| 154 | /// @return Returns true if the isolate could be configured. Unless this |
| 155 | /// returns true, the engine will not move the isolate to the |
| 156 | /// `DartIsolate::Phase::Ready` phase for subsequent run. |
| 157 | /// |
| 158 | [[nodiscard]] bool PrepareIsolate(DartIsolate& isolate); |
| 159 | |
| 160 | virtual bool IsNullSafetyEnabled(const DartSnapshot& snapshot) = 0; |
| 161 | |
| 162 | protected: |
| 163 | virtual bool DoPrepareIsolate(DartIsolate& isolate) = 0; |
| 164 | |
| 165 | private: |
| 166 | FML_DISALLOW_COPY_AND_ASSIGN(IsolateConfiguration); |
| 167 | }; |
| 168 | |
| 169 | } // namespace flutter |
| 170 | |
| 171 | #endif // FLUTTER_SHELL_RUNTIME_ISOLATE_CONFIGURATION_H_ |
| 172 | |