15c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/* 25c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2008 Apple Inc. All Rights Reserved. 35c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 45c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Redistribution and use in source and binary forms, with or without 55c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * modification, are permitted provided that the following conditions 65c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * are met: 75c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 1. Redistributions of source code must retain the above copyright 85c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * notice, this list of conditions and the following disclaimer. 95c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 2. Redistributions in binary form must reproduce the above copyright 105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * notice, this list of conditions and the following disclaimer in the 115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * documentation and/or other materials provided with the distribution. 125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY 145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR 175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */ 265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "config.h" 285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/workers/WorkerThread.h" 305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "bindings/v8/ScriptSourceCode.h" 3253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/inspector/InspectorInstrumentation.h" 33591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch#include "core/workers/DedicatedWorkerGlobalScope.h" 347757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch#include "core/workers/WorkerClients.h" 357757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch#include "core/workers/WorkerThreadStartupData.h" 3653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "modules/webdatabase/DatabaseManager.h" 3753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "modules/webdatabase/DatabaseTask.h" 381e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)#include "platform/PlatformThreadData.h" 3951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)#include "platform/weborigin/KURL.h" 405267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)#include "public/platform/Platform.h" 415267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)#include "public/platform/WebWorkerRunLoop.h" 42521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)#include "wtf/Noncopyable.h" 43521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)#include "wtf/text/WTFString.h" 44521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) 45521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)#include <utility> 465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)namespace WebCore { 485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 49926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)static Mutex& threadSetMutex() 505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) AtomicallyInitializedStatic(Mutex&, mutex = *new Mutex); 525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return mutex; 535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 55926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)static HashSet<WorkerThread*>& workerThreads() 56926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){ 57926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) DEFINE_STATIC_LOCAL(HashSet<WorkerThread*>, threads, ()); 58926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return threads; 59926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)} 605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)unsigned WorkerThread::workerThreadCount() 625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 63926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) MutexLocker lock(threadSetMutex()); 64926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return workerThreads().size(); 655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 677757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen MurdochWorkerThread::WorkerThread(WorkerLoaderProxy& workerLoaderProxy, WorkerReportingProxy& workerReportingProxy, PassOwnPtr<WorkerThreadStartupData> startupData) 685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) : m_threadID(0) 695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) , m_workerLoaderProxy(workerLoaderProxy) 705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) , m_workerReportingProxy(workerReportingProxy) 717757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch , m_startupData(startupData) 725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) , m_notificationClient(0) 735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 74926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) MutexLocker lock(threadSetMutex()); 75926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) workerThreads().add(this); 765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)WorkerThread::~WorkerThread() 795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 80926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) MutexLocker lock(threadSetMutex()); 81926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) ASSERT(workerThreads().contains(this)); 82926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) workerThreads().remove(this); 835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool WorkerThread::start() 865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Mutex protection is necessary to ensure that m_threadID is initialized when the thread starts. 885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) MutexLocker lock(m_threadCreationMutex); 895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (m_threadID) 915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return true; 925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_threadID = createThread(WorkerThread::workerThreadStart, this, "WebCore: Worker"); 945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return m_threadID; 965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void WorkerThread::workerThreadStart(void* thread) 995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) static_cast<WorkerThread*>(thread)->workerThread(); 1015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void WorkerThread::workerThread() 1045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1057757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch KURL scriptURL = m_startupData->m_scriptURL; 1067757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch String sourceCode = m_startupData->m_sourceCode; 1077757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch WorkerThreadStartMode startMode = m_startupData->m_startMode; 1087757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch 1095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 1105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) MutexLocker lock(m_threadCreationMutex); 1117757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch 1127757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch m_workerGlobalScope = createWorkerGlobalScope(m_startupData.release()); 1135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (m_runLoop.terminated()) { 1155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // The worker was terminated before the thread had a chance to run. Since the context didn't exist yet, 1165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // forbidExecution() couldn't be called from stop(). 117591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch m_workerGlobalScope->script()->forbidExecution(); 1185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // The corresponding call to didStopWorkerRunLoop is in 1215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // ~WorkerScriptController. 12251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) blink::Platform::current()->didStartWorkerRunLoop(blink::WebWorkerRunLoop(&m_runLoop)); 1235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 124591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch WorkerScriptController* script = m_workerGlobalScope->script(); 1257757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch InspectorInstrumentation::willEvaluateWorkerScript(workerGlobalScope(), startMode); 1267757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch script->evaluate(ScriptSourceCode(sourceCode, scriptURL)); 1275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) runEventLoop(); 1295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ThreadIdentifier threadID = m_threadID; 1315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 132591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch ASSERT(m_workerGlobalScope->hasOneRef()); 1335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // The below assignment will destroy the context, which will in turn notify messaging proxy. 1355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // We cannot let any objects survive past thread exit, because no other thread will run GC or otherwise destroy them. 136591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch m_workerGlobalScope = 0; 1375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1381e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) // Clean up PlatformThreadData before WTF::WTFThreadData goes away! 1391e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) PlatformThreadData::current().destroy(); 1405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // The thread object may be already destroyed from notification now, don't try to access "this". 1425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) detachThread(threadID); 1435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void WorkerThread::runEventLoop() 1465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Does not return until terminated. 148591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch m_runLoop.run(m_workerGlobalScope.get()); 1495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1511e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)class WorkerThreadShutdownFinishTask : public ExecutionContextTask { 1525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)public: 1535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) static PassOwnPtr<WorkerThreadShutdownFinishTask> create() 1545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 1555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return adoptPtr(new WorkerThreadShutdownFinishTask()); 1565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1581e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) virtual void performTask(ExecutionContext *context) 1595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 160591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch WorkerGlobalScope* workerGlobalScope = toWorkerGlobalScope(context); 161591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch workerGlobalScope->clearInspector(); 1625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // It's not safe to call clearScript until all the cleanup tasks posted by functions initiated by WorkerThreadShutdownStartTask have completed. 163591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch workerGlobalScope->clearScript(); 1645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) virtual bool isCleanupTask() const { return true; } 1675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}; 1685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1691e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)class WorkerThreadShutdownStartTask : public ExecutionContextTask { 1705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)public: 1715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) static PassOwnPtr<WorkerThreadShutdownStartTask> create() 1725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 1735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return adoptPtr(new WorkerThreadShutdownStartTask()); 1745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1761e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) virtual void performTask(ExecutionContext *context) 1775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 178591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch WorkerGlobalScope* workerGlobalScope = toWorkerGlobalScope(context); 1795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // FIXME: Should we stop the databases as part of stopActiveDOMObjects() below? 1815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) DatabaseTaskSynchronizer cleanupSync; 182591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch DatabaseManager::manager().stopDatabases(workerGlobalScope, &cleanupSync); 1835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 184591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch workerGlobalScope->stopActiveDOMObjects(); 1855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 186591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch workerGlobalScope->notifyObserversOfStop(); 1875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Event listeners would keep DOMWrapperWorld objects alive for too long. Also, they have references to JS objects, 1895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // which become dangling once Heap is destroyed. 190591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch workerGlobalScope->removeAllEventListeners(); 1915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // We wait for the database thread to clean up all its stuff so that we 1935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // can do more stringent leak checks as we exit. 1945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) cleanupSync.waitForTaskCompletion(); 1955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Stick a shutdown command at the end of the queue, so that we deal 1975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // with all the cleanup tasks the databases post first. 198591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch workerGlobalScope->postTask(WorkerThreadShutdownFinishTask::create()); 1995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) virtual bool isCleanupTask() const { return true; } 2025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}; 2035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void WorkerThread::stop() 2055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 2065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Mutex protection is necessary because stop() can be called before the context is fully created. 2075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) MutexLocker lock(m_threadCreationMutex); 2085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // 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. 210591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch if (m_workerGlobalScope) { 211591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch m_workerGlobalScope->script()->scheduleExecutionTermination(); 2125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 213591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch DatabaseManager::manager().interruptAllDatabasesForContext(m_workerGlobalScope.get()); 214926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) m_runLoop.postTaskAndTerminate(WorkerThreadShutdownStartTask::create()); 215926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return; 2165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_runLoop.terminate(); 2185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 22093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)bool WorkerThread::isCurrentThread() const 22193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles){ 22293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) return m_threadID == currentThread(); 22393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)} 22493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) 2251e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)class ReleaseFastMallocFreeMemoryTask : public ExecutionContextTask { 2261e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) virtual void performTask(ExecutionContext*) OVERRIDE { WTF::releaseFastMallocFreeMemory(); } 227926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)}; 228926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 229926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)void WorkerThread::releaseFastMallocFreeMemoryInAllThreads() 230926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){ 231926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) MutexLocker lock(threadSetMutex()); 232926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) HashSet<WorkerThread*>& threads = workerThreads(); 233926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) HashSet<WorkerThread*>::iterator end = threads.end(); 234926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) for (HashSet<WorkerThread*>::iterator it = threads.begin(); it != end; ++it) 235926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) (*it)->runLoop().postTask(adoptPtr(new ReleaseFastMallocFreeMemoryTask)); 236926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)} 237926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 2385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} // namespace WebCore 239