virtual void performTask(ScriptExecutionContext *context) { WorkerGlobalScope* workerGlobalScope = toWorkerGlobalScope(context); #if ENABLE(SQL_DATABASE) // FIXME: Should we stop the databases as part of stopActiveDOMObjects() below? DatabaseTaskSynchronizer cleanupSync; DatabaseManager::manager().stopDatabases(workerGlobalScope, &cleanupSync); #endif workerGlobalScope->stopActiveDOMObjects(); workerGlobalScope->notifyObserversOfStop(); // Event listeners would keep DOMWrapperWorld objects alive for too long. Also, they have references to JS objects, // which become dangling once Heap is destroyed. workerGlobalScope->removeAllEventListeners(); #if ENABLE(SQL_DATABASE) // We wait for the database thread to clean up all its stuff so that we // can do more stringent leak checks as we exit. cleanupSync.waitForTaskCompletion(); #endif // Stick a shutdown command at the end of the queue, so that we deal // with all the cleanup tasks the databases post first. workerGlobalScope->postTask(WorkerThreadShutdownFinishTask::create()); }
void WorkerThread::stop() { // Mutex protection is necessary because stop() can be called before the context is fully created. MutexLocker lock(m_threadCreationMutex); // Ensure that tasks are being handled by thread event loop. If script execution weren't forbidden, a while(1) loop in JS could keep the thread alive forever. if (m_workerGlobalScope) { m_workerGlobalScope->script()->scheduleExecutionTermination(); #if ENABLE(SQL_DATABASE) DatabaseManager::manager().interruptAllDatabasesForContext(m_workerGlobalScope.get()); #endif m_runLoop.postTaskAndTerminate({ ScriptExecutionContext::Task::CleanupTask, [] (ScriptExecutionContext* context ) { WorkerGlobalScope* workerGlobalScope = toWorkerGlobalScope(context); #if ENABLE(SQL_DATABASE) // FIXME: Should we stop the databases as part of stopActiveDOMObjects() below? DatabaseTaskSynchronizer cleanupSync; DatabaseManager::manager().stopDatabases(workerGlobalScope, &cleanupSync); #endif workerGlobalScope->stopActiveDOMObjects(); workerGlobalScope->notifyObserversOfStop(); // Event listeners would keep DOMWrapperWorld objects alive for too long. Also, they have references to JS objects, // which become dangling once Heap is destroyed. workerGlobalScope->removeAllEventListeners(); #if ENABLE(SQL_DATABASE) // We wait for the database thread to clean up all its stuff so that we // can do more stringent leak checks as we exit. cleanupSync.waitForTaskCompletion(); #endif // Stick a shutdown command at the end of the queue, so that we deal // with all the cleanup tasks the databases post first. workerGlobalScope->postTask({ ScriptExecutionContext::Task::CleanupTask, [] (ScriptExecutionContext* context) { WorkerGlobalScope* workerGlobalScope = toWorkerGlobalScope(context); // It's not safe to call clearScript until all the cleanup tasks posted by functions initiated by WorkerThreadShutdownStartTask have completed. workerGlobalScope->clearScript(); } }); } }); return; } m_runLoop.terminate(); }