10bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch/* 20bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * Copyright (C) 2009 Google Inc. All rights reserved. 30bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * 40bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * Redistribution and use in source and binary forms, with or without 50bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * modification, are permitted provided that the following conditions are 60bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * met: 70bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * 80bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * * Redistributions of source code must retain the above copyright 90bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * notice, this list of conditions and the following disclaimer. 100bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * * Redistributions in binary form must reproduce the above 110bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * copyright notice, this list of conditions and the following disclaimer 120bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * in the documentation and/or other materials provided with the 130bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * distribution. 140bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * * Neither the name of Google Inc. nor the names of its 150bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * contributors may be used to endorse or promote products derived from 160bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * this software without specific prior written permission. 170bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * 180bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 190bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 200bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 210bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 220bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 230bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 240bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 250bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 260bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 270bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 280bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 290bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch */ 300bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 310bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#include "config.h" 320bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 330bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#if ENABLE(SHARED_WORKERS) 340bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 350bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#include "DefaultSharedWorkerRepository.h" 360bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 370bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#include "ActiveDOMObject.h" 38e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block#include "CrossThreadTask.h" 39231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#include "Document.h" 4065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#include "InspectorInstrumentation.h" 41231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#include "MessageEvent.h" 420bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#include "MessagePort.h" 430bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#include "NotImplemented.h" 440bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#include "PlatformString.h" 45ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch#include "ScriptCallStack.h" 460bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#include "SecurityOrigin.h" 470bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#include "SecurityOriginHash.h" 480bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#include "SharedWorker.h" 490bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#include "SharedWorkerContext.h" 50231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#include "SharedWorkerRepository.h" 510bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#include "SharedWorkerThread.h" 520bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#include "WorkerLoaderProxy.h" 53231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#include "WorkerReportingProxy.h" 540bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#include "WorkerScriptLoader.h" 550bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#include "WorkerScriptLoaderClient.h" 56231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#include <wtf/HashSet.h> 570bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#include <wtf/Threading.h> 580bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 590bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochnamespace WebCore { 600bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 612bde8e466a4451c7319e3a072d118917957d6554Steve Blockclass SharedWorkerProxy : public ThreadSafeRefCounted<SharedWorkerProxy>, public WorkerLoaderProxy, public WorkerReportingProxy { 620bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochpublic: 63231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block static PassRefPtr<SharedWorkerProxy> create(const String& name, const KURL& url, PassRefPtr<SecurityOrigin> origin) { return adoptRef(new SharedWorkerProxy(name, url, origin)); } 640bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 650bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch void setThread(PassRefPtr<SharedWorkerThread> thread) { m_thread = thread; } 660bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch SharedWorkerThread* thread() { return m_thread.get(); } 67231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block bool isClosing() const { return m_closing; } 68231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block KURL url() const 69231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block { 70231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block // Don't use m_url.copy() because it isn't a threadsafe method. 71231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block return KURL(ParsedURLString, m_url.string().threadsafeCopy()); 72231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block } 73231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 74231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block String name() const { return m_name.threadsafeCopy(); } 75231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block bool matches(const String& name, PassRefPtr<SecurityOrigin> origin, const KURL& urlToMatch) const; 760bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 770bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch // WorkerLoaderProxy 78643ca7872b450ea4efacab6188849e5aac2ba161Steve Block virtual void postTaskToLoader(PassOwnPtr<ScriptExecutionContext::Task>); 79643ca7872b450ea4efacab6188849e5aac2ba161Steve Block virtual void postTaskForModeToWorkerContext(PassOwnPtr<ScriptExecutionContext::Task>, const String&); 80231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 81231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block // WorkerReportingProxy 82231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block virtual void postExceptionToWorkerObject(const String& errorMessage, int lineNumber, const String& sourceURL); 83dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block virtual void postConsoleMessageToWorkerObject(MessageSource, MessageType, MessageLevel, const String& message, int lineNumber, const String& sourceURL); 84231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block virtual void workerContextClosed(); 85231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block virtual void workerContextDestroyed(); 860bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 870bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch // Updates the list of the worker's documents, per section 4.5 of the WebWorkers spec. 880bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch void addToWorkerDocuments(ScriptExecutionContext*); 89231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 90231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block bool isInWorkerDocuments(Document* document) { return m_workerDocuments.contains(document); } 91231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 92231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block // Removes a detached document from the list of worker's documents. May set the closing flag if this is the last document in the list. 93231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block void documentDetached(Document*); 94231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 950bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochprivate: 96231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block SharedWorkerProxy(const String& name, const KURL&, PassRefPtr<SecurityOrigin>); 97231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block void close(); 98231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 990bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch bool m_closing; 1000bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch String m_name; 1010bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch KURL m_url; 102231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block // The thread is freed when the proxy is destroyed, so we need to make sure that the proxy stays around until the SharedWorkerContext exits. 1030bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch RefPtr<SharedWorkerThread> m_thread; 104231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block RefPtr<SecurityOrigin> m_origin; 105231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block HashSet<Document*> m_workerDocuments; 106231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block // Ensures exclusive access to the worker documents. Must not grab any other locks (such as the DefaultSharedWorkerRepository lock) while holding this one. 107231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block Mutex m_workerDocumentsLock; 1080bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch}; 1090bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 110231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve BlockSharedWorkerProxy::SharedWorkerProxy(const String& name, const KURL& url, PassRefPtr<SecurityOrigin> origin) 1110bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch : m_closing(false) 112231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block , m_name(name.crossThreadString()) 1130bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch , m_url(url.copy()) 114231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block , m_origin(origin) 115231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{ 116231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block // We should be the sole owner of the SecurityOrigin, as we will free it on another thread. 117231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block ASSERT(m_origin->hasOneRef()); 118231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block} 119231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 120231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockbool SharedWorkerProxy::matches(const String& name, PassRefPtr<SecurityOrigin> origin, const KURL& urlToMatch) const 121231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{ 122231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block // If the origins don't match, or the names don't match, then this is not the proxy we are looking for. 123231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (!origin->equal(m_origin.get())) 124231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block return false; 125231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 126231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block // If the names are both empty, compares the URLs instead per the Web Workers spec. 127231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (name.isEmpty() && m_name.isEmpty()) 128231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block return urlToMatch == url(); 129231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 130231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block return name == m_name; 131231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block} 132231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 133643ca7872b450ea4efacab6188849e5aac2ba161Steve Blockvoid SharedWorkerProxy::postTaskToLoader(PassOwnPtr<ScriptExecutionContext::Task> task) 134231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{ 135231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block MutexLocker lock(m_workerDocumentsLock); 136231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 137231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (isClosing()) 138231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block return; 139231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 140231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block // If we aren't closing, then we must have at least one document. 141231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block ASSERT(m_workerDocuments.size()); 142231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 143231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block // Just pick an arbitrary active document from the HashSet and pass load requests to it. 144231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block // FIXME: Do we need to deal with the case where the user closes the document mid-load, via a shadow document or some other solution? 145231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block Document* document = *(m_workerDocuments.begin()); 146231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block document->postTask(task); 147231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block} 148231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 149643ca7872b450ea4efacab6188849e5aac2ba161Steve Blockvoid SharedWorkerProxy::postTaskForModeToWorkerContext(PassOwnPtr<ScriptExecutionContext::Task> task, const String& mode) 150231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{ 151231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (isClosing()) 152231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block return; 153231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block ASSERT(m_thread); 154231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block m_thread->runLoop().postTaskForMode(task, mode); 155231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block} 156231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 157231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockstatic void postExceptionTask(ScriptExecutionContext* context, const String& errorMessage, int lineNumber, const String& sourceURL) 158231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{ 159ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch context->reportException(errorMessage, lineNumber, sourceURL, 0); 160231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block} 161231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 162231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockvoid SharedWorkerProxy::postExceptionToWorkerObject(const String& errorMessage, int lineNumber, const String& sourceURL) 163231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{ 164231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block MutexLocker lock(m_workerDocumentsLock); 165231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block for (HashSet<Document*>::iterator iter = m_workerDocuments.begin(); iter != m_workerDocuments.end(); ++iter) 166231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block (*iter)->postTask(createCallbackTask(&postExceptionTask, errorMessage, lineNumber, sourceURL)); 167231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block} 168231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 169dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockstatic void postConsoleMessageTask(ScriptExecutionContext* document, MessageSource source, MessageType type, MessageLevel level, const String& message, unsigned lineNumber, const String& sourceURL) 170231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{ 171ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch document->addMessage(source, type, level, message, lineNumber, sourceURL, 0); 172231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block} 173231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 174dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockvoid SharedWorkerProxy::postConsoleMessageToWorkerObject(MessageSource source, MessageType type, MessageLevel level, const String& message, int lineNumber, const String& sourceURL) 175231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{ 176231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block MutexLocker lock(m_workerDocumentsLock); 177231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block for (HashSet<Document*>::iterator iter = m_workerDocuments.begin(); iter != m_workerDocuments.end(); ++iter) 178dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block (*iter)->postTask(createCallbackTask(&postConsoleMessageTask, source, type, level, message, lineNumber, sourceURL)); 179231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block} 180231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 181231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockvoid SharedWorkerProxy::workerContextClosed() 182231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{ 183231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (isClosing()) 184231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block return; 185231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block close(); 186231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block} 187231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 188231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockvoid SharedWorkerProxy::workerContextDestroyed() 1890bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{ 190231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block // The proxy may be freed by this call, so do not reference it any further. 191231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block DefaultSharedWorkerRepository::instance().removeProxy(this); 1920bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch} 1930bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 1940bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochvoid SharedWorkerProxy::addToWorkerDocuments(ScriptExecutionContext* context) 1950bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{ 1960bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch // Nested workers are not yet supported, so passed-in context should always be a Document. 1970bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch ASSERT(context->isDocument()); 198231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block ASSERT(!isClosing()); 199231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block MutexLocker lock(m_workerDocumentsLock); 200231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block Document* document = static_cast<Document*>(context); 201231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block m_workerDocuments.add(document); 202231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block} 203231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 204231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockvoid SharedWorkerProxy::documentDetached(Document* document) 205231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{ 206231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (isClosing()) 207231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block return; 208231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block // Remove the document from our set (if it's there) and if that was the last document in the set, mark the proxy as closed. 209231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block MutexLocker lock(m_workerDocumentsLock); 210231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block m_workerDocuments.remove(document); 211231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (!m_workerDocuments.size()) 212231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block close(); 213231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block} 214231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 215231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockvoid SharedWorkerProxy::close() 216231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{ 217231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block ASSERT(!isClosing()); 218231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block m_closing = true; 219231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block // Stop the worker thread - the proxy will stay around until we get workerThreadExited() notification. 220231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (m_thread) 221231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block m_thread->stop(); 2220bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch} 2230bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 2240bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochclass SharedWorkerConnectTask : public ScriptExecutionContext::Task { 2250bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochpublic: 226643ca7872b450ea4efacab6188849e5aac2ba161Steve Block static PassOwnPtr<SharedWorkerConnectTask> create(PassOwnPtr<MessagePortChannel> channel) 2270bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch { 228643ca7872b450ea4efacab6188849e5aac2ba161Steve Block return new SharedWorkerConnectTask(channel); 2290bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch } 2300bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 2310bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochprivate: 2320bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch SharedWorkerConnectTask(PassOwnPtr<MessagePortChannel> channel) 2330bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch : m_channel(channel) 2340bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch { 2350bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch } 2360bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 2370bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch virtual void performTask(ScriptExecutionContext* scriptContext) 2380bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch { 2390bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch RefPtr<MessagePort> port = MessagePort::create(*scriptContext); 2400bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch port->entangle(m_channel.release()); 2410bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch ASSERT(scriptContext->isWorkerContext()); 2420bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch WorkerContext* workerContext = static_cast<WorkerContext*>(scriptContext); 243231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block // Since close() stops the thread event loop, this should not ever get called while closing. 244231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block ASSERT(!workerContext->isClosing()); 2450bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch ASSERT(workerContext->isSharedWorkerContext()); 246231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block workerContext->toSharedWorkerContext()->dispatchEvent(createConnectEvent(port)); 2470bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch } 2480bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 2490bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch OwnPtr<MessagePortChannel> m_channel; 2500bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch}; 2510bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 2520bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch// Loads the script on behalf of a worker. 2535e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Blockclass SharedWorkerScriptLoader : public RefCounted<SharedWorkerScriptLoader>, private WorkerScriptLoaderClient { 2540bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochpublic: 2550bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch SharedWorkerScriptLoader(PassRefPtr<SharedWorker>, PassOwnPtr<MessagePortChannel>, PassRefPtr<SharedWorkerProxy>); 2560bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch void load(const KURL&); 2570bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 2580bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochprivate: 2590bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch // WorkerScriptLoaderClient callback 2600bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch virtual void notifyFinished(); 2610bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 2620bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch RefPtr<SharedWorker> m_worker; 2630bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch OwnPtr<MessagePortChannel> m_port; 2640bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch RefPtr<SharedWorkerProxy> m_proxy; 2650bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch OwnPtr<WorkerScriptLoader> m_scriptLoader; 2660bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch}; 2670bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 2680bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben MurdochSharedWorkerScriptLoader::SharedWorkerScriptLoader(PassRefPtr<SharedWorker> worker, PassOwnPtr<MessagePortChannel> port, PassRefPtr<SharedWorkerProxy> proxy) 2695e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block : m_worker(worker) 2700bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch , m_port(port) 2710bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch , m_proxy(proxy) 2720bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{ 2730bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch} 2740bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 2750bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochvoid SharedWorkerScriptLoader::load(const KURL& url) 2760bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{ 2770bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch // Mark this object as active for the duration of the load. 27821939df44de1705786c545cd1bf519d47250322dBen Murdoch m_scriptLoader = new WorkerScriptLoader(ResourceRequestBase::TargetIsSharedWorker); 2795e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block m_scriptLoader->loadAsynchronously(m_worker->scriptExecutionContext(), url, DenyCrossOriginRequests, this); 2800bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 2815e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block // Stay alive (and keep the SharedWorker and JS wrapper alive) until the load finishes. 2825e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block this->ref(); 283231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block m_worker->setPendingActivity(m_worker.get()); 2840bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch} 2850bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 2860bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochvoid SharedWorkerScriptLoader::notifyFinished() 2870bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{ 2885e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block // FIXME: This method is not guaranteed to be invoked if we are loading from WorkerContext (see comment for WorkerScriptLoaderClient::notifyFinished()). 2895e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block // We need to address this before supporting nested workers. 2905e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block 2910bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch // Hand off the just-loaded code to the repository to start up the worker thread. 2920bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (m_scriptLoader->failed()) 293231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block m_worker->dispatchEvent(Event::create(eventNames().errorEvent, false, true)); 294dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block else { 29565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch InspectorInstrumentation::scriptImported(m_worker->scriptExecutionContext(), m_scriptLoader->identifier(), m_scriptLoader->script()); 2965e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block DefaultSharedWorkerRepository::instance().workerScriptLoaded(*m_proxy, m_worker->scriptExecutionContext()->userAgent(m_scriptLoader->url()), m_scriptLoader->script(), m_port.release()); 297dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block } 298231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block m_worker->unsetPendingActivity(m_worker.get()); 2995e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block this->deref(); // This frees this object - must be the last action in this function. 3000bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch} 3010bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 3020bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben MurdochDefaultSharedWorkerRepository& DefaultSharedWorkerRepository::instance() 3030bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{ 3040bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch AtomicallyInitializedStatic(DefaultSharedWorkerRepository*, instance = new DefaultSharedWorkerRepository); 3050bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch return *instance; 3060bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch} 3070bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 3080bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochvoid DefaultSharedWorkerRepository::workerScriptLoaded(SharedWorkerProxy& proxy, const String& userAgent, const String& workerScript, PassOwnPtr<MessagePortChannel> port) 3090bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{ 3100bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch MutexLocker lock(m_lock); 311231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (proxy.isClosing()) 3120bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch return; 3130bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 3140bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch // Another loader may have already started up a thread for this proxy - if so, just send a connect to the pre-existing thread. 3150bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (!proxy.thread()) { 316231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block RefPtr<SharedWorkerThread> thread = SharedWorkerThread::create(proxy.name(), proxy.url(), userAgent, workerScript, proxy, proxy); 3170bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch proxy.setThread(thread); 3180bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch thread->start(); 3190bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch } 3200bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch proxy.thread()->runLoop().postTask(SharedWorkerConnectTask::create(port)); 3210bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch} 3220bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 323231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockbool SharedWorkerRepository::isAvailable() 324231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{ 325231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block // SharedWorkers are enabled on the default WebKit platform. 326231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block return true; 327231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block} 328231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 3290bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochvoid SharedWorkerRepository::connect(PassRefPtr<SharedWorker> worker, PassOwnPtr<MessagePortChannel> port, const KURL& url, const String& name, ExceptionCode& ec) 3300bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{ 3310bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch DefaultSharedWorkerRepository::instance().connectToWorker(worker, port, url, name, ec); 3320bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch} 3330bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 334231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockvoid SharedWorkerRepository::documentDetached(Document* document) 335231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{ 336231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block DefaultSharedWorkerRepository::instance().documentDetached(document); 337231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block} 338231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 339231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockbool SharedWorkerRepository::hasSharedWorkers(Document* document) 340231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{ 341231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block return DefaultSharedWorkerRepository::instance().hasSharedWorkers(document); 342231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block} 343231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 344231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockbool DefaultSharedWorkerRepository::hasSharedWorkers(Document* document) 345231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{ 346231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block MutexLocker lock(m_lock); 347231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block for (unsigned i = 0; i < m_proxies.size(); i++) { 348231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (m_proxies[i]->isInWorkerDocuments(document)) 349231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block return true; 350231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block } 351231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block return false; 352231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block} 353231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 354231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockvoid DefaultSharedWorkerRepository::removeProxy(SharedWorkerProxy* proxy) 355231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{ 356231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block MutexLocker lock(m_lock); 357231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block for (unsigned i = 0; i < m_proxies.size(); i++) { 358231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (proxy == m_proxies[i].get()) { 359231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block m_proxies.remove(i); 360231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block return; 361231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block } 362231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block } 363231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block} 364231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 365231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockvoid DefaultSharedWorkerRepository::documentDetached(Document* document) 366231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{ 367231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block MutexLocker lock(m_lock); 368231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block for (unsigned i = 0; i < m_proxies.size(); i++) 369231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block m_proxies[i]->documentDetached(document); 370231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block} 371231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 3720bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochvoid DefaultSharedWorkerRepository::connectToWorker(PassRefPtr<SharedWorker> worker, PassOwnPtr<MessagePortChannel> port, const KURL& url, const String& name, ExceptionCode& ec) 3730bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{ 3740bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch MutexLocker lock(m_lock); 3750bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch ASSERT(worker->scriptExecutionContext()->securityOrigin()->canAccess(SecurityOrigin::create(url).get())); 3760bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch // Fetch a proxy corresponding to this SharedWorker. 3770bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch RefPtr<SharedWorkerProxy> proxy = getProxy(name, url); 3780bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch proxy->addToWorkerDocuments(worker->scriptExecutionContext()); 3790bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (proxy->url() != url) { 3800bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch // Proxy already existed under alternate URL - return an error. 3810bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch ec = URL_MISMATCH_ERR; 3820bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch return; 3830bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch } 3840bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch // If proxy is already running, just connect to it - otherwise, kick off a loader to load the script. 3850bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (proxy->thread()) 3860bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch proxy->thread()->runLoop().postTask(SharedWorkerConnectTask::create(port)); 3870bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch else { 388e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke RefPtr<SharedWorkerScriptLoader> loader = adoptRef(new SharedWorkerScriptLoader(worker, port, proxy.release())); 3890bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch loader->load(url); 3900bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch } 3910bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch} 3920bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 3930bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch// Creates a new SharedWorkerProxy or returns an existing one from the repository. Must only be called while the repository mutex is held. 3940bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben MurdochPassRefPtr<SharedWorkerProxy> DefaultSharedWorkerRepository::getProxy(const String& name, const KURL& url) 3950bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{ 3960bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch // Look for an existing worker, and create one if it doesn't exist. 397231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block // Items in the cache are freed on another thread, so do a threadsafe copy of the URL before creating the origin, 398231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block // to make sure no references to external strings linger. 399231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block RefPtr<SecurityOrigin> origin = SecurityOrigin::create(KURL(ParsedURLString, url.string().threadsafeCopy())); 400231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block for (unsigned i = 0; i < m_proxies.size(); i++) { 401231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (!m_proxies[i]->isClosing() && m_proxies[i]->matches(name, origin, url)) 402231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block return m_proxies[i]; 4030bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch } 404231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block // Proxy is not in the repository currently - create a new one. 405231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block RefPtr<SharedWorkerProxy> proxy = SharedWorkerProxy::create(name, url, origin.release()); 406231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block m_proxies.append(proxy); 407231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block return proxy.release(); 4080bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch} 4090bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 4100bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben MurdochDefaultSharedWorkerRepository::DefaultSharedWorkerRepository() 4110bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{ 4120bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch} 4130bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 4140bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben MurdochDefaultSharedWorkerRepository::~DefaultSharedWorkerRepository() 4150bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{ 4160bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch} 4170bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 4180bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch} // namespace WebCore 4190bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 4200bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#endif // ENABLE(SHARED_WORKERS) 421