| 170 | _debuggerService = nullptr; |
| 171 | } |
| 172 | |
| 173 | SharedRuntime RuntimeManager::createRuntime(const Shared<IResourceLoader>& resourceLoader, |
| 174 | double displayScale, |
| 175 | const Ref<MainThreadManager>& mainThreadManagerOverride, |
| 176 | std::optional<PlatformType> platformType) { |
| 177 | auto runtime = Valdi::makeShared<Runtime>(_attributeIds, |
| 178 | platformType ? platformType.value() : _platformType, |
| 179 | mainThreadManagerOverride != nullptr ? mainThreadManagerOverride : |
| 180 | _mainThreadManager, |
| 181 | _jsBridge, |
| 182 | _workerQueue, |
| 183 | _jsThreadQoS, |
| 184 | _userSession, |
| 185 | _keychain, |
| 186 | resourceLoader, |
| 187 | _assetLoaderManager, |
| 188 | _requestManager, |
| 189 | _colorPalette, |
| 190 | _diskCache, |
| 191 | _yogaConfig, |
| 192 | _runtimeMessageHandler, |
| 193 | _anrDetector, |
| 194 | displayScale, |
| 195 | _debuggerService != nullptr, |
| 196 | _logger); |
| 197 | |
| 198 | std::vector<std::shared_ptr<::snap::valdi_core::ModuleFactory>> moduleFactories; |
| 199 | std::vector<RegisteredTypeConverter> typeConverters; |
| 200 | std::vector<Ref<IRuntimeManagerListener>> listeners; |
| 201 | Ref<AttributionResolver> attributionResolver; |
| 202 | Ref<Metrics> metrics; |
| 203 | |
| 204 | bool shouldInit = true; |
| 205 | bool autoRenderDisabled; |
| 206 | { |
| 207 | std::lock_guard<Mutex> guard(_mutex); |
| 208 | removeExpiredRuntimes(); |
| 209 | _runtimes.emplace_back(runtime); |
| 210 | shouldInit = !_disableRuntimeAutoInit; |
| 211 | moduleFactories = _registeredModuleFactories; |
| 212 | typeConverters = _registeredTypeConverters; |
| 213 | listeners = _listeners; |
| 214 | attributionResolver = _attributionResolver; |
| 215 | metrics = _metrics; |
| 216 | autoRenderDisabled = _loadOperationsCount > 0; |
| 217 | // Apply state that has a peer RuntimeManager::set*() iterating runtimes |
| 218 | // while still holding _mutex. If we read into a local and applied after |
| 219 | // releasing the lock, a concurrent setter could interleave: it would |
| 220 | // see the just-added runtime in its snapshot and apply the new value |
| 221 | // to it, and we would then overwrite with our stale local copy. |
| 222 | // |
| 223 | // Runtime::set*() below only takes the ResourceManager's mutex (a |
| 224 | // different one), so there is no lock-inversion risk. This mirrors how |
| 225 | // the peer setters (e.g. setMmapCacheDirectory, setTweakValueProvider) |
| 226 | // already operate on runtimes they iterate. |
| 227 | runtime->setMmapCacheDirectory(_mmapCacheDirectory); |
| 228 | runtime->setRuntimeTweaks(_runtimeTweaks); |
| 229 | } |
nothing calls this directly
no test coverage detected