Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 * Copyright (C) 2008 Apple Inc. All Rights Reserved. | 2 * Copyright (C) 2008 Apple Inc. All Rights Reserved. |
| 3 * | 3 * |
| 4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
| 5 * modification, are permitted provided that the following conditions | 5 * modification, are permitted provided that the following conditions |
| 6 * are met: | 6 * are met: |
| 7 * 1. Redistributions of source code must retain the above copyright | 7 * 1. Redistributions of source code must retain the above copyright |
| 8 * notice, this list of conditions and the following disclaimer. | 8 * notice, this list of conditions and the following disclaimer. |
| 9 * 2. Redistributions in binary form must reproduce the above copyright | 9 * 2. Redistributions in binary form must reproduce the above copyright |
| 10 * notice, this list of conditions and the following disclaimer in the | 10 * notice, this list of conditions and the following disclaimer in the |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 26 | 26 |
| 27 #include "config.h" | 27 #include "config.h" |
| 28 | 28 |
| 29 #include "core/workers/WorkerThread.h" | 29 #include "core/workers/WorkerThread.h" |
| 30 | 30 |
| 31 #include "bindings/v8/ScriptSourceCode.h" | 31 #include "bindings/v8/ScriptSourceCode.h" |
| 32 #include "bindings/v8/ScriptValue.h" | 32 #include "bindings/v8/ScriptValue.h" |
| 33 #include "core/inspector/InspectorInstrumentation.h" | 33 #include "core/inspector/InspectorInstrumentation.h" |
| 34 #include "core/platform/KURL.h" | 34 #include "core/platform/KURL.h" |
| 35 #include "core/platform/ThreadGlobalData.h" | 35 #include "core/platform/ThreadGlobalData.h" |
| 36 #include "core/platform/Task.h" | |
| 36 #include "core/workers/DedicatedWorkerContext.h" | 37 #include "core/workers/DedicatedWorkerContext.h" |
| 37 #include "modules/webdatabase/DatabaseManager.h" | 38 #include "modules/webdatabase/DatabaseManager.h" |
| 38 #include "modules/webdatabase/DatabaseTask.h" | 39 #include "modules/webdatabase/DatabaseTask.h" |
| 39 | 40 |
| 40 #include <utility> | 41 #include <utility> |
| 41 #include <wtf/Noncopyable.h> | 42 #include <wtf/Noncopyable.h> |
| 42 #include <wtf/text/WTFString.h> | 43 #include <wtf/text/WTFString.h> |
| 43 | 44 |
| 44 #include <public/Platform.h> | 45 #include <public/Platform.h> |
| 45 #include <public/WebWorkerRunLoop.h> | 46 #include <public/WebWorkerRunLoop.h> |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 96 if (!settings) | 97 if (!settings) |
| 97 return; | 98 return; |
| 98 | 99 |
| 99 m_groupSettings = GroupSettings::create(); | 100 m_groupSettings = GroupSettings::create(); |
| 100 m_groupSettings->setLocalStorageQuotaBytes(settings->localStorageQuotaBytes( )); | 101 m_groupSettings->setLocalStorageQuotaBytes(settings->localStorageQuotaBytes( )); |
| 101 m_groupSettings->setIndexedDBQuotaBytes(settings->indexedDBQuotaBytes()); | 102 m_groupSettings->setIndexedDBQuotaBytes(settings->indexedDBQuotaBytes()); |
| 102 m_groupSettings->setIndexedDBDatabasePath(settings->indexedDBDatabasePath(). isolatedCopy()); | 103 m_groupSettings->setIndexedDBDatabasePath(settings->indexedDBDatabasePath(). isolatedCopy()); |
| 103 } | 104 } |
| 104 | 105 |
| 105 WorkerThread::WorkerThread(const KURL& scriptURL, const String& userAgent, const GroupSettings* settings, const String& sourceCode, WorkerLoaderProxy& workerLoa derProxy, WorkerReportingProxy& workerReportingProxy, WorkerThreadStartMode star tMode, const String& contentSecurityPolicy, ContentSecurityPolicy::HeaderType co ntentSecurityPolicyType, const SecurityOrigin* topOrigin) | 106 WorkerThread::WorkerThread(const KURL& scriptURL, const String& userAgent, const GroupSettings* settings, const String& sourceCode, WorkerLoaderProxy& workerLoa derProxy, WorkerReportingProxy& workerReportingProxy, WorkerThreadStartMode star tMode, const String& contentSecurityPolicy, ContentSecurityPolicy::HeaderType co ntentSecurityPolicyType, const SecurityOrigin* topOrigin) |
| 106 : m_threadID(0) | 107 : m_workerLoaderProxy(workerLoaderProxy) |
| 107 , m_workerLoaderProxy(workerLoaderProxy) | |
| 108 , m_workerReportingProxy(workerReportingProxy) | 108 , m_workerReportingProxy(workerReportingProxy) |
| 109 , m_startupData(WorkerThreadStartupData::create(scriptURL, userAgent, settin gs, sourceCode, startMode, contentSecurityPolicy, contentSecurityPolicyType, top Origin)) | 109 , m_startupData(WorkerThreadStartupData::create(scriptURL, userAgent, settin gs, sourceCode, startMode, contentSecurityPolicy, contentSecurityPolicyType, top Origin)) |
| 110 #if ENABLE(NOTIFICATIONS) || ENABLE(LEGACY_NOTIFICATIONS) | 110 #if ENABLE(NOTIFICATIONS) || ENABLE(LEGACY_NOTIFICATIONS) |
| 111 , m_notificationClient(0) | 111 , m_notificationClient(0) |
| 112 #endif | 112 #endif |
| 113 { | 113 { |
| 114 MutexLocker lock(threadSetMutex()); | 114 MutexLocker lock(threadSetMutex()); |
| 115 workerThreads().add(this); | 115 workerThreads().add(this); |
| 116 } | 116 } |
| 117 | 117 |
| 118 WorkerThread::~WorkerThread() | 118 WorkerThread::~WorkerThread() |
| 119 { | 119 { |
| 120 MutexLocker lock(threadSetMutex()); | 120 MutexLocker lock(threadSetMutex()); |
| 121 ASSERT(workerThreads().contains(this)); | 121 ASSERT(workerThreads().contains(this)); |
| 122 workerThreads().remove(this); | 122 workerThreads().remove(this); |
| 123 } | 123 } |
| 124 | 124 |
| 125 bool WorkerThread::start() | 125 bool WorkerThread::start() |
| 126 { | 126 { |
| 127 // Mutex protection is necessary to ensure that m_threadID is initialized wh en the thread starts. | 127 // Mutex protection is necessary to ensure that m_thread is initialized when the thread starts. |
| 128 MutexLocker lock(m_threadCreationMutex); | 128 MutexLocker lock(m_threadCreationMutex); |
| 129 | 129 |
| 130 if (m_threadID) | 130 if (m_thread) |
| 131 return true; | 131 return true; |
| 132 | 132 |
| 133 m_threadID = createThread(WorkerThread::workerThreadStart, this, "WebCore: W orker"); | 133 m_thread = adoptPtr(WebKit::Platform::current()->createThread("WebCore: Work er")); |
| 134 | 134 m_thread->postTask(new Task(bind(&WorkerThread::workerThread, this))); |
| 135 return m_threadID; | 135 return true; |
| 136 } | |
| 137 | |
| 138 void WorkerThread::workerThreadStart(void* thread) | |
| 139 { | |
| 140 static_cast<WorkerThread*>(thread)->workerThread(); | |
| 141 } | 136 } |
| 142 | 137 |
| 143 void WorkerThread::workerThread() | 138 void WorkerThread::workerThread() |
| 144 { | 139 { |
| 145 { | 140 { |
| 146 MutexLocker lock(m_threadCreationMutex); | 141 MutexLocker lock(m_threadCreationMutex); |
| 147 m_workerContext = createWorkerContext(m_startupData->m_scriptURL, m_star tupData->m_userAgent, m_startupData->m_groupSettings.release(), m_startupData->m _contentSecurityPolicy, m_startupData->m_contentSecurityPolicyType, m_startupDat a->m_topOrigin.release()); | 142 m_workerContext = createWorkerContext(m_startupData->m_scriptURL, m_star tupData->m_userAgent, m_startupData->m_groupSettings.release(), m_startupData->m _contentSecurityPolicy, m_startupData->m_contentSecurityPolicyType, m_startupDat a->m_topOrigin.release()); |
| 148 | 143 |
| 149 if (m_runLoop.terminated()) { | 144 if (m_runLoop.terminated()) { |
| 150 // The worker was terminated before the thread had a chance to run. Since the context didn't exist yet, | 145 // The worker was terminated before the thread had a chance to run. Since the context didn't exist yet, |
| 151 // forbidExecution() couldn't be called from stop(). | 146 // forbidExecution() couldn't be called from stop(). |
| 152 m_workerContext->script()->forbidExecution(); | 147 m_workerContext->script()->forbidExecution(); |
| 153 } | 148 } |
| 154 } | 149 } |
| 155 // The corresponding call to didStopWorkerRunLoop is in | 150 // The corresponding call to didStopWorkerRunLoop is in |
| 156 // ~WorkerScriptController. | 151 // ~WorkerScriptController. |
| 157 WebKit::Platform::current()->didStartWorkerRunLoop(WebKit::WebWorkerRunLoop( &m_runLoop)); | 152 WebKit::Platform::current()->didStartWorkerRunLoop(WebKit::WebWorkerRunLoop( &m_runLoop)); |
| 158 | 153 |
| 159 WorkerScriptController* script = m_workerContext->script(); | 154 WorkerScriptController* script = m_workerContext->script(); |
| 160 InspectorInstrumentation::willEvaluateWorkerScript(workerContext(), m_startu pData->m_startMode); | 155 InspectorInstrumentation::willEvaluateWorkerScript(workerContext(), m_startu pData->m_startMode); |
| 161 script->evaluate(ScriptSourceCode(m_startupData->m_sourceCode, m_startupData ->m_scriptURL)); | 156 script->evaluate(ScriptSourceCode(m_startupData->m_sourceCode, m_startupData ->m_scriptURL)); |
| 162 // Free the startup data to cause its member variable deref's happen on the worker's thread (since | 157 // Free the startup data to cause its member variable deref's happen on the worker's thread (since |
| 163 // all ref/derefs of these objects are happening on the thread at this point ). Note that | 158 // all ref/derefs of these objects are happening on the thread at this point ). Note that |
| 164 // WorkerThread::~WorkerThread happens on a different thread where it was cr eated. | 159 // WorkerThread::~WorkerThread happens on a different thread where it was cr eated. |
| 165 m_startupData.clear(); | 160 m_startupData.clear(); |
| 166 | 161 |
| 167 runEventLoop(); | 162 runEventLoop(); |
| 168 | 163 |
| 169 ThreadIdentifier threadID = m_threadID; | |
| 170 | |
| 171 ASSERT(m_workerContext->hasOneRef()); | 164 ASSERT(m_workerContext->hasOneRef()); |
| 172 | 165 |
| 173 // The below assignment will destroy the context, which will in turn notify messaging proxy. | 166 // The below assignment will destroy the context, which will in turn notify messaging proxy. |
| 174 // We cannot let any objects survive past thread exit, because no other thre ad will run GC or otherwise destroy them. | 167 // We cannot let any objects survive past thread exit, because no other thre ad will run GC or otherwise destroy them. |
| 175 m_workerContext = 0; | 168 m_workerContext = 0; |
| 176 | 169 |
| 177 // Clean up WebCore::ThreadGlobalData before WTF::WTFThreadData goes away! | 170 // Clean up WebCore::ThreadGlobalData before WTF::WTFThreadData goes away! |
| 178 threadGlobalData().destroy(); | 171 threadGlobalData().destroy(); |
| 179 | |
| 180 // The thread object may be already destroyed from notification now, don't t ry to access "this". | |
| 181 detachThread(threadID); | |
|
jamesr
2013/05/20 20:56:29
hmm, should we make an explicit effort to kill the
abarth-chromium
2013/05/20 21:00:36
Yes, I tried for a while having this code release(
| |
| 182 } | 172 } |
| 183 | 173 |
| 184 void WorkerThread::runEventLoop() | 174 void WorkerThread::runEventLoop() |
| 185 { | 175 { |
| 186 // Does not return until terminated. | 176 // Does not return until terminated. |
| 187 m_runLoop.run(m_workerContext.get()); | 177 m_runLoop.run(m_workerContext.get()); |
| 188 } | 178 } |
| 189 | 179 |
| 190 class WorkerThreadShutdownFinishTask : public ScriptExecutionContext::Task { | 180 class WorkerThreadShutdownFinishTask : public ScriptExecutionContext::Task { |
| 191 public: | 181 public: |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 251 if (m_workerContext) { | 241 if (m_workerContext) { |
| 252 m_workerContext->script()->scheduleExecutionTermination(); | 242 m_workerContext->script()->scheduleExecutionTermination(); |
| 253 | 243 |
| 254 DatabaseManager::manager().interruptAllDatabasesForContext(m_workerConte xt.get()); | 244 DatabaseManager::manager().interruptAllDatabasesForContext(m_workerConte xt.get()); |
| 255 m_runLoop.postTaskAndTerminate(WorkerThreadShutdownStartTask::create()); | 245 m_runLoop.postTaskAndTerminate(WorkerThreadShutdownStartTask::create()); |
| 256 return; | 246 return; |
| 257 } | 247 } |
| 258 m_runLoop.terminate(); | 248 m_runLoop.terminate(); |
| 259 } | 249 } |
| 260 | 250 |
| 251 bool WorkerThread::isCurrentThread() const | |
| 252 { | |
| 253 return m_thread->isCurrentThread(); | |
| 254 } | |
| 255 | |
| 261 class ReleaseFastMallocFreeMemoryTask : public ScriptExecutionContext::Task { | 256 class ReleaseFastMallocFreeMemoryTask : public ScriptExecutionContext::Task { |
| 262 virtual void performTask(ScriptExecutionContext*) OVERRIDE { WTF::releaseFas tMallocFreeMemory(); } | 257 virtual void performTask(ScriptExecutionContext*) OVERRIDE { WTF::releaseFas tMallocFreeMemory(); } |
| 263 }; | 258 }; |
| 264 | 259 |
| 265 void WorkerThread::releaseFastMallocFreeMemoryInAllThreads() | 260 void WorkerThread::releaseFastMallocFreeMemoryInAllThreads() |
| 266 { | 261 { |
| 267 MutexLocker lock(threadSetMutex()); | 262 MutexLocker lock(threadSetMutex()); |
| 268 HashSet<WorkerThread*>& threads = workerThreads(); | 263 HashSet<WorkerThread*>& threads = workerThreads(); |
| 269 HashSet<WorkerThread*>::iterator end = threads.end(); | 264 HashSet<WorkerThread*>::iterator end = threads.end(); |
| 270 for (HashSet<WorkerThread*>::iterator it = threads.begin(); it != end; ++it) | 265 for (HashSet<WorkerThread*>::iterator it = threads.begin(); it != end; ++it) |
| 271 (*it)->runLoop().postTask(adoptPtr(new ReleaseFastMallocFreeMemoryTask)) ; | 266 (*it)->runLoop().postTask(adoptPtr(new ReleaseFastMallocFreeMemoryTask)) ; |
| 272 } | 267 } |
| 273 | 268 |
| 274 } // namespace WebCore | 269 } // namespace WebCore |
| OLD | NEW |