| 369 | } |
| 370 | |
| 371 | void JavaScriptRuntime::teardown(bool destroyContext) { |
| 372 | auto wasDisposed = _isDisposed.exchange(true); |
| 373 | if (wasDisposed) { |
| 374 | return; |
| 375 | } |
| 376 | |
| 377 | // Just in case postInit() was never called |
| 378 | _initLock.leaveIfNotCompleted(); |
| 379 | |
| 380 | // Workers share this runtime's listener (see createWorker); detach them so a worker |
| 381 | // outliving this runtime does not keep a dangling reference. A worker task holding a |
| 382 | // RetainedListener keeps the listener's owner alive until the call completes. |
| 383 | for (const auto& jsWorker : getAllWorkers()) { |
| 384 | jsWorker->setListener(nullptr, {}); |
| 385 | } |
| 386 | |
| 387 | if (destroyContext) { |
| 388 | _dispatchQueue->sync([&]() { |
| 389 | if (_anrDetector != nullptr) { |
| 390 | _anrDetector->removeTaskScheduler(this); |
| 391 | } |
| 392 | // Prevent further dispatches to run |
| 393 | setListener(nullptr, {}); |
| 394 | _dispatchQueue->fullTeardown(); |
| 395 | |
| 396 | if (!destroyContext) { |
| 397 | return; |
| 398 | } |
| 399 | |
| 400 | // Bridged objects should be deallocated immediately |
| 401 | auto nonDeferredPool = Valdi::RefCountableAutoreleasePool::makeNonDeferred(); |
| 402 | |
| 403 | _globalContext->releaseDisposables(); |
| 404 | _contextManager.destroyContext(_globalContext); |
| 405 | |
| 406 | _modules.clear(); |
| 407 | _daemonClients.clear(); |
| 408 | _moduleLoader = JSValueRef(); |
| 409 | _symbolicateFunction = Result<JSValueRef>(); |
| 410 | _onDaemonClientEventFunction = Result<JSValueRef>(); |
| 411 | _uncaughtExceptionHandler = nullptr; |
| 412 | _unhandledRejectionHandler = nullptr; |
| 413 | if (_contextHandler != nullptr) { |
| 414 | _contextHandler->clear(); |
| 415 | _contextHandler = nullptr; |
| 416 | } |
| 417 | _runtimeDeserializers = nullptr; |
| 418 | _propertyNameIndex.setContext(nullptr); |
| 419 | auto weakJavaScriptContext = weakRef(_javaScriptContext.get()); |
| 420 | _javaScriptContext = nullptr; |
| 421 | |
| 422 | SC_ASSERT(weakJavaScriptContext.expired()); |
| 423 | }); |
| 424 | } else { |
| 425 | if (_anrDetector != nullptr) { |
| 426 | _anrDetector->removeTaskScheduler(this); |
| 427 | } |
no test coverage detected