summaryrefslogtreecommitdiffstats
path: root/Source/WebCore/workers
diff options
context:
space:
mode:
authorSteve Block <steveblock@google.com>2011-05-06 11:45:16 +0100
committerSteve Block <steveblock@google.com>2011-05-12 13:44:10 +0100
commitcad810f21b803229eb11403f9209855525a25d57 (patch)
tree29a6fd0279be608e0fe9ffe9841f722f0f4e4269 /Source/WebCore/workers
parent121b0cf4517156d0ac5111caf9830c51b69bae8f (diff)
downloadexternal_webkit-cad810f21b803229eb11403f9209855525a25d57.zip
external_webkit-cad810f21b803229eb11403f9209855525a25d57.tar.gz
external_webkit-cad810f21b803229eb11403f9209855525a25d57.tar.bz2
Merge WebKit at r75315: Initial merge by git.
Change-Id: I570314b346ce101c935ed22a626b48c2af266b84
Diffstat (limited to 'Source/WebCore/workers')
-rw-r--r--Source/WebCore/workers/AbstractWorker.cpp104
-rw-r--r--Source/WebCore/workers/AbstractWorker.h83
-rw-r--r--Source/WebCore/workers/AbstractWorker.idl51
-rw-r--r--Source/WebCore/workers/DedicatedWorkerContext.cpp85
-rw-r--r--Source/WebCore/workers/DedicatedWorkerContext.h74
-rw-r--r--Source/WebCore/workers/DedicatedWorkerContext.idl57
-rw-r--r--Source/WebCore/workers/DedicatedWorkerThread.cpp71
-rw-r--r--Source/WebCore/workers/DedicatedWorkerThread.h60
-rw-r--r--Source/WebCore/workers/DefaultSharedWorkerRepository.cpp422
-rw-r--r--Source/WebCore/workers/DefaultSharedWorkerRepository.h90
-rw-r--r--Source/WebCore/workers/SharedWorker.cpp81
-rw-r--r--Source/WebCore/workers/SharedWorker.h60
-rw-r--r--Source/WebCore/workers/SharedWorker.idl47
-rw-r--r--Source/WebCore/workers/SharedWorkerContext.cpp69
-rw-r--r--Source/WebCore/workers/SharedWorkerContext.h73
-rw-r--r--Source/WebCore/workers/SharedWorkerContext.idl47
-rw-r--r--Source/WebCore/workers/SharedWorkerRepository.h70
-rw-r--r--Source/WebCore/workers/SharedWorkerThread.cpp63
-rw-r--r--Source/WebCore/workers/SharedWorkerThread.h56
-rw-r--r--Source/WebCore/workers/Worker.cpp150
-rw-r--r--Source/WebCore/workers/Worker.h90
-rw-r--r--Source/WebCore/workers/Worker.idl53
-rw-r--r--Source/WebCore/workers/WorkerContext.cpp444
-rw-r--r--Source/WebCore/workers/WorkerContext.h200
-rw-r--r--Source/WebCore/workers/WorkerContext.idl127
-rw-r--r--Source/WebCore/workers/WorkerContextProxy.h67
-rw-r--r--Source/WebCore/workers/WorkerLoaderProxy.h63
-rw-r--r--Source/WebCore/workers/WorkerLocation.cpp85
-rw-r--r--Source/WebCore/workers/WorkerLocation.h72
-rw-r--r--Source/WebCore/workers/WorkerLocation.idl47
-rw-r--r--Source/WebCore/workers/WorkerMessagingProxy.cpp383
-rw-r--r--Source/WebCore/workers/WorkerMessagingProxy.h110
-rw-r--r--Source/WebCore/workers/WorkerObjectProxy.h60
-rw-r--r--Source/WebCore/workers/WorkerReportingProxy.h61
-rw-r--r--Source/WebCore/workers/WorkerRunLoop.cpp210
-rw-r--r--Source/WebCore/workers/WorkerRunLoop.h96
-rw-r--r--Source/WebCore/workers/WorkerScriptLoader.cpp171
-rw-r--r--Source/WebCore/workers/WorkerScriptLoader.h85
-rw-r--r--Source/WebCore/workers/WorkerScriptLoaderClient.h53
-rw-r--r--Source/WebCore/workers/WorkerThread.cpp248
-rw-r--r--Source/WebCore/workers/WorkerThread.h106
41 files changed, 4644 insertions, 0 deletions
diff --git a/Source/WebCore/workers/AbstractWorker.cpp b/Source/WebCore/workers/AbstractWorker.cpp
new file mode 100644
index 0000000..10bc95f
--- /dev/null
+++ b/Source/WebCore/workers/AbstractWorker.cpp
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#if ENABLE(WORKERS)
+
+#include "AbstractWorker.h"
+
+#include "ErrorEvent.h"
+#include "Event.h"
+#include "EventException.h"
+#include "EventNames.h"
+#include "InspectorController.h"
+#include "ScriptExecutionContext.h"
+#include "SecurityOrigin.h"
+
+namespace WebCore {
+
+AbstractWorker::AbstractWorker(ScriptExecutionContext* context)
+ : ActiveDOMObject(context, this)
+{
+}
+
+AbstractWorker::~AbstractWorker()
+{
+ onDestroyWorker();
+}
+
+void AbstractWorker::onDestroyWorker()
+{
+#if ENABLE(INSPECTOR)
+ if (InspectorController* inspector = scriptExecutionContext() ? scriptExecutionContext()->inspectorController() : 0)
+ inspector->didDestroyWorker(asID());
+#endif
+}
+
+void AbstractWorker::contextDestroyed()
+{
+ onDestroyWorker();
+ ActiveDOMObject::contextDestroyed();
+}
+
+KURL AbstractWorker::resolveURL(const String& url, ExceptionCode& ec)
+{
+ if (url.isEmpty()) {
+ ec = SYNTAX_ERR;
+ return KURL();
+ }
+
+ // FIXME: This should use the dynamic global scope (bug #27887)
+ KURL scriptURL = scriptExecutionContext()->completeURL(url);
+ if (!scriptURL.isValid()) {
+ ec = SYNTAX_ERR;
+ return KURL();
+ }
+
+ if (!scriptExecutionContext()->securityOrigin()->canAccess(SecurityOrigin::create(scriptURL).get())) {
+ ec = SECURITY_ERR;
+ return KURL();
+ }
+ return scriptURL;
+}
+
+EventTargetData* AbstractWorker::eventTargetData()
+{
+ return &m_eventTargetData;
+}
+
+EventTargetData* AbstractWorker::ensureEventTargetData()
+{
+ return &m_eventTargetData;
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(WORKERS)
diff --git a/Source/WebCore/workers/AbstractWorker.h b/Source/WebCore/workers/AbstractWorker.h
new file mode 100644
index 0000000..f4cc50b
--- /dev/null
+++ b/Source/WebCore/workers/AbstractWorker.h
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef AbstractWorker_h
+#define AbstractWorker_h
+
+#if ENABLE(WORKERS)
+
+#include "ActiveDOMObject.h"
+#include "EventListener.h"
+#include "EventNames.h"
+#include "EventTarget.h"
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefCounted.h>
+#include <wtf/RefPtr.h>
+#include <wtf/text/AtomicStringHash.h>
+
+namespace WebCore {
+
+ class KURL;
+ class ScriptExecutionContext;
+
+ class AbstractWorker : public RefCounted<AbstractWorker>, public ActiveDOMObject, public EventTarget {
+ public:
+ // EventTarget APIs
+ virtual ScriptExecutionContext* scriptExecutionContext() const { return ActiveDOMObject::scriptExecutionContext(); }
+
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(error);
+
+ using RefCounted<AbstractWorker>::ref;
+ using RefCounted<AbstractWorker>::deref;
+
+ virtual void contextDestroyed();
+ AbstractWorker(ScriptExecutionContext*);
+ virtual ~AbstractWorker();
+
+ protected:
+ // Helper function that converts a URL to an absolute URL and checks the result for validity.
+ KURL resolveURL(const String& url, ExceptionCode& ec);
+ intptr_t asID() const { return reinterpret_cast<intptr_t>(this); }
+
+ private:
+ virtual void refEventTarget() { ref(); }
+ virtual void derefEventTarget() { deref(); }
+ virtual EventTargetData* eventTargetData();
+ virtual EventTargetData* ensureEventTargetData();
+ void onDestroyWorker();
+
+ EventTargetData m_eventTargetData;
+ };
+
+} // namespace WebCore
+
+#endif // ENABLE(WORKERS)
+
+#endif // AbstractWorker_h
diff --git a/Source/WebCore/workers/AbstractWorker.idl b/Source/WebCore/workers/AbstractWorker.idl
new file mode 100644
index 0000000..f05ec17
--- /dev/null
+++ b/Source/WebCore/workers/AbstractWorker.idl
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+module threads {
+
+ interface [
+ Conditional=WORKERS,
+ CustomToJS,
+ EventTarget
+ ] AbstractWorker {
+
+ attribute EventListener onerror;
+
+ void addEventListener(in DOMString type,
+ in EventListener listener,
+ in boolean useCapture);
+ void removeEventListener(in DOMString type,
+ in EventListener listener,
+ in boolean useCapture);
+ boolean dispatchEvent(in Event evt)
+ raises(EventException);
+ };
+
+}
diff --git a/Source/WebCore/workers/DedicatedWorkerContext.cpp b/Source/WebCore/workers/DedicatedWorkerContext.cpp
new file mode 100644
index 0000000..54b5ba8
--- /dev/null
+++ b/Source/WebCore/workers/DedicatedWorkerContext.cpp
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#if ENABLE(WORKERS)
+
+#include "DedicatedWorkerContext.h"
+
+#include "DedicatedWorkerThread.h"
+#include "DOMWindow.h"
+#include "MessageEvent.h"
+#include "WorkerObjectProxy.h"
+
+namespace WebCore {
+
+DedicatedWorkerContext::DedicatedWorkerContext(const KURL& url, const String& userAgent, DedicatedWorkerThread* thread)
+ : WorkerContext(url, userAgent, thread)
+{
+}
+
+// FIXME: remove this when we update the ObjC bindings (bug #28774).
+void DedicatedWorkerContext::postMessage(PassRefPtr<SerializedScriptValue> message, MessagePort* port, ExceptionCode& ec)
+{
+ MessagePortArray ports;
+ if (port)
+ ports.append(port);
+ postMessage(message, &ports, ec);
+}
+
+void DedicatedWorkerContext::postMessage(PassRefPtr<SerializedScriptValue> message, ExceptionCode& ec)
+{
+ postMessage(message, static_cast<MessagePortArray*>(0), ec);
+}
+
+void DedicatedWorkerContext::postMessage(PassRefPtr<SerializedScriptValue> message, const MessagePortArray* ports, ExceptionCode& ec)
+{
+ // Disentangle the port in preparation for sending it to the remote context.
+ OwnPtr<MessagePortChannelArray> channels = MessagePort::disentanglePorts(ports, ec);
+ if (ec)
+ return;
+ thread()->workerObjectProxy().postMessageToWorkerObject(message, channels.release());
+}
+
+void DedicatedWorkerContext::importScripts(const Vector<String>& urls, ExceptionCode& ec)
+{
+ Base::importScripts(urls, ec);
+ thread()->workerObjectProxy().reportPendingActivity(hasPendingActivity());
+}
+
+DedicatedWorkerThread* DedicatedWorkerContext::thread()
+{
+ return static_cast<DedicatedWorkerThread*>(Base::thread());
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(WORKERS)
diff --git a/Source/WebCore/workers/DedicatedWorkerContext.h b/Source/WebCore/workers/DedicatedWorkerContext.h
new file mode 100644
index 0000000..dba52ae
--- /dev/null
+++ b/Source/WebCore/workers/DedicatedWorkerContext.h
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef DedicatedWorkerContext_h
+#define DedicatedWorkerContext_h
+
+#if ENABLE(WORKERS)
+
+#include "MessagePort.h"
+#include "WorkerContext.h"
+
+namespace WebCore {
+
+ class DedicatedWorkerThread;
+
+ class DedicatedWorkerContext : public WorkerContext {
+ public:
+ typedef WorkerContext Base;
+ static PassRefPtr<DedicatedWorkerContext> create(const KURL& url, const String& userAgent, DedicatedWorkerThread* thread)
+ {
+ return adoptRef(new DedicatedWorkerContext(url, userAgent, thread));
+ }
+
+ virtual bool isDedicatedWorkerContext() const { return true; }
+
+ // Overridden to allow us to check our pending activity after executing imported script.
+ virtual void importScripts(const Vector<String>& urls, ExceptionCode&);
+
+ // EventTarget
+ virtual DedicatedWorkerContext* toDedicatedWorkerContext() { return this; }
+ void postMessage(PassRefPtr<SerializedScriptValue>, ExceptionCode&);
+ void postMessage(PassRefPtr<SerializedScriptValue>, const MessagePortArray*, ExceptionCode&);
+ // FIXME: remove this when we update the ObjC bindings (bug #28774).
+ void postMessage(PassRefPtr<SerializedScriptValue>, MessagePort*, ExceptionCode&);
+
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(message);
+
+ DedicatedWorkerThread* thread();
+ private:
+ DedicatedWorkerContext(const KURL&, const String&, DedicatedWorkerThread*);
+ };
+
+} // namespace WebCore
+
+#endif // ENABLE(WORKERS)
+
+#endif // DedicatedWorkerContext_h
diff --git a/Source/WebCore/workers/DedicatedWorkerContext.idl b/Source/WebCore/workers/DedicatedWorkerContext.idl
new file mode 100644
index 0000000..22d3525
--- /dev/null
+++ b/Source/WebCore/workers/DedicatedWorkerContext.idl
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+module threads {
+
+ interface [
+ Conditional=WORKERS,
+ ExtendsDOMGlobalObject,
+ IsWorkerContext,
+ GenerateNativeConverter,
+ NoStaticTables,
+ OmitConstructor
+ ] DedicatedWorkerContext : WorkerContext {
+
+#if !defined(LANGUAGE_CPP) || !LANGUAGE_CPP
+#if defined(LANGUAGE_JAVASCRIPT) && LANGUAGE_JAVASCRIPT
+ [Custom] void postMessage(in any message, in [Optional] Array messagePorts)
+ raises(DOMException);
+#else
+ // There's no good way to expose an array via the ObjC bindings, so for now just allow passing in a single port.
+ void postMessage(in DOMString message, in [Optional] MessagePort messagePort)
+ raises(DOMException);
+#endif
+#endif
+
+ attribute EventListener onmessage;
+
+ };
+
+}
diff --git a/Source/WebCore/workers/DedicatedWorkerThread.cpp b/Source/WebCore/workers/DedicatedWorkerThread.cpp
new file mode 100644
index 0000000..d4789a1
--- /dev/null
+++ b/Source/WebCore/workers/DedicatedWorkerThread.cpp
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#if ENABLE(WORKERS)
+
+#include "DedicatedWorkerThread.h"
+
+#include "DedicatedWorkerContext.h"
+#include "WorkerObjectProxy.h"
+
+namespace WebCore {
+
+PassRefPtr<DedicatedWorkerThread> DedicatedWorkerThread::create(const KURL& scriptURL, const String& userAgent, const String& sourceCode, WorkerLoaderProxy& workerLoaderProxy, WorkerObjectProxy& workerObjectProxy)
+{
+ return adoptRef(new DedicatedWorkerThread(scriptURL, userAgent, sourceCode, workerLoaderProxy, workerObjectProxy));
+}
+
+DedicatedWorkerThread::DedicatedWorkerThread(const KURL& url, const String& userAgent, const String& sourceCode, WorkerLoaderProxy& workerLoaderProxy, WorkerObjectProxy& workerObjectProxy)
+ : WorkerThread(url, userAgent, sourceCode, workerLoaderProxy, workerObjectProxy)
+ , m_workerObjectProxy(workerObjectProxy)
+{
+}
+
+DedicatedWorkerThread::~DedicatedWorkerThread()
+{
+}
+
+PassRefPtr<WorkerContext> DedicatedWorkerThread::createWorkerContext(const KURL& url, const String& userAgent)
+{
+ return DedicatedWorkerContext::create(url, userAgent, this);
+}
+
+void DedicatedWorkerThread::runEventLoop()
+{
+ // Notify the parent object of our current active state before calling the superclass to run the event loop.
+ m_workerObjectProxy.reportPendingActivity(workerContext()->hasPendingActivity());
+ WorkerThread::runEventLoop();
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(WORKERS)
diff --git a/Source/WebCore/workers/DedicatedWorkerThread.h b/Source/WebCore/workers/DedicatedWorkerThread.h
new file mode 100644
index 0000000..225243b
--- /dev/null
+++ b/Source/WebCore/workers/DedicatedWorkerThread.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef DedicatedWorkerThread_h
+#define DedicatedWorkerThread_h
+
+#if ENABLE(WORKERS)
+
+#include "WorkerThread.h"
+
+namespace WebCore {
+
+ class WorkerObjectProxy;
+
+ class DedicatedWorkerThread : public WorkerThread {
+ public:
+ static PassRefPtr<DedicatedWorkerThread> create(const KURL& scriptURL, const String& userAgent, const String& sourceCode, WorkerLoaderProxy&, WorkerObjectProxy&);
+ WorkerObjectProxy& workerObjectProxy() const { return m_workerObjectProxy; }
+ ~DedicatedWorkerThread();
+
+ protected:
+ virtual PassRefPtr<WorkerContext> createWorkerContext(const KURL& url, const String& userAgent);
+ virtual void runEventLoop();
+
+ private:
+ DedicatedWorkerThread(const KURL&, const String& userAgent, const String& sourceCode, WorkerLoaderProxy&, WorkerObjectProxy&);
+
+ WorkerObjectProxy& m_workerObjectProxy;
+ };
+} // namespace WebCore
+
+#endif // ENABLE(WORKERS)
+
+#endif // DedicatedWorkerThread_h
diff --git a/Source/WebCore/workers/DefaultSharedWorkerRepository.cpp b/Source/WebCore/workers/DefaultSharedWorkerRepository.cpp
new file mode 100644
index 0000000..4a8e947
--- /dev/null
+++ b/Source/WebCore/workers/DefaultSharedWorkerRepository.cpp
@@ -0,0 +1,422 @@
+/*
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#if ENABLE(SHARED_WORKERS)
+
+#include "DefaultSharedWorkerRepository.h"
+
+#include "ActiveDOMObject.h"
+#include "CrossThreadTask.h"
+#include "Document.h"
+#include "InspectorController.h"
+#include "MessageEvent.h"
+#include "MessagePort.h"
+#include "NotImplemented.h"
+#include "PlatformString.h"
+#include "SecurityOrigin.h"
+#include "SecurityOriginHash.h"
+#include "SharedWorker.h"
+#include "SharedWorkerContext.h"
+#include "SharedWorkerRepository.h"
+#include "SharedWorkerThread.h"
+#include "WorkerLoaderProxy.h"
+#include "WorkerReportingProxy.h"
+#include "WorkerScriptLoader.h"
+#include "WorkerScriptLoaderClient.h"
+#include <wtf/HashSet.h>
+#include <wtf/Threading.h>
+
+namespace WebCore {
+
+class SharedWorkerProxy : public ThreadSafeShared<SharedWorkerProxy>, public WorkerLoaderProxy, public WorkerReportingProxy {
+public:
+ static PassRefPtr<SharedWorkerProxy> create(const String& name, const KURL& url, PassRefPtr<SecurityOrigin> origin) { return adoptRef(new SharedWorkerProxy(name, url, origin)); }
+
+ void setThread(PassRefPtr<SharedWorkerThread> thread) { m_thread = thread; }
+ SharedWorkerThread* thread() { return m_thread.get(); }
+ bool isClosing() const { return m_closing; }
+ KURL url() const
+ {
+ // Don't use m_url.copy() because it isn't a threadsafe method.
+ return KURL(ParsedURLString, m_url.string().threadsafeCopy());
+ }
+
+ String name() const { return m_name.threadsafeCopy(); }
+ bool matches(const String& name, PassRefPtr<SecurityOrigin> origin, const KURL& urlToMatch) const;
+
+ // WorkerLoaderProxy
+ virtual void postTaskToLoader(PassOwnPtr<ScriptExecutionContext::Task>);
+ virtual void postTaskForModeToWorkerContext(PassOwnPtr<ScriptExecutionContext::Task>, const String&);
+
+ // WorkerReportingProxy
+ virtual void postExceptionToWorkerObject(const String& errorMessage, int lineNumber, const String& sourceURL);
+ virtual void postConsoleMessageToWorkerObject(MessageSource, MessageType, MessageLevel, const String& message, int lineNumber, const String& sourceURL);
+ virtual void workerContextClosed();
+ virtual void workerContextDestroyed();
+
+ // Updates the list of the worker's documents, per section 4.5 of the WebWorkers spec.
+ void addToWorkerDocuments(ScriptExecutionContext*);
+
+ bool isInWorkerDocuments(Document* document) { return m_workerDocuments.contains(document); }
+
+ // 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.
+ void documentDetached(Document*);
+
+private:
+ SharedWorkerProxy(const String& name, const KURL&, PassRefPtr<SecurityOrigin>);
+ void close();
+
+ bool m_closing;
+ String m_name;
+ KURL m_url;
+ // The thread is freed when the proxy is destroyed, so we need to make sure that the proxy stays around until the SharedWorkerContext exits.
+ RefPtr<SharedWorkerThread> m_thread;
+ RefPtr<SecurityOrigin> m_origin;
+ HashSet<Document*> m_workerDocuments;
+ // Ensures exclusive access to the worker documents. Must not grab any other locks (such as the DefaultSharedWorkerRepository lock) while holding this one.
+ Mutex m_workerDocumentsLock;
+};
+
+SharedWorkerProxy::SharedWorkerProxy(const String& name, const KURL& url, PassRefPtr<SecurityOrigin> origin)
+ : m_closing(false)
+ , m_name(name.crossThreadString())
+ , m_url(url.copy())
+ , m_origin(origin)
+{
+ // We should be the sole owner of the SecurityOrigin, as we will free it on another thread.
+ ASSERT(m_origin->hasOneRef());
+}
+
+bool SharedWorkerProxy::matches(const String& name, PassRefPtr<SecurityOrigin> origin, const KURL& urlToMatch) const
+{
+ // If the origins don't match, or the names don't match, then this is not the proxy we are looking for.
+ if (!origin->equal(m_origin.get()))
+ return false;
+
+ // If the names are both empty, compares the URLs instead per the Web Workers spec.
+ if (name.isEmpty() && m_name.isEmpty())
+ return urlToMatch == url();
+
+ return name == m_name;
+}
+
+void SharedWorkerProxy::postTaskToLoader(PassOwnPtr<ScriptExecutionContext::Task> task)
+{
+ MutexLocker lock(m_workerDocumentsLock);
+
+ if (isClosing())
+ return;
+
+ // If we aren't closing, then we must have at least one document.
+ ASSERT(m_workerDocuments.size());
+
+ // Just pick an arbitrary active document from the HashSet and pass load requests to it.
+ // 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?
+ Document* document = *(m_workerDocuments.begin());
+ document->postTask(task);
+}
+
+void SharedWorkerProxy::postTaskForModeToWorkerContext(PassOwnPtr<ScriptExecutionContext::Task> task, const String& mode)
+{
+ if (isClosing())
+ return;
+ ASSERT(m_thread);
+ m_thread->runLoop().postTaskForMode(task, mode);
+}
+
+static void postExceptionTask(ScriptExecutionContext* context, const String& errorMessage, int lineNumber, const String& sourceURL)
+{
+ context->reportException(errorMessage, lineNumber, sourceURL);
+}
+
+void SharedWorkerProxy::postExceptionToWorkerObject(const String& errorMessage, int lineNumber, const String& sourceURL)
+{
+ MutexLocker lock(m_workerDocumentsLock);
+ for (HashSet<Document*>::iterator iter = m_workerDocuments.begin(); iter != m_workerDocuments.end(); ++iter)
+ (*iter)->postTask(createCallbackTask(&postExceptionTask, errorMessage, lineNumber, sourceURL));
+}
+
+static void postConsoleMessageTask(ScriptExecutionContext* document, MessageSource source, MessageType type, MessageLevel level, const String& message, unsigned lineNumber, const String& sourceURL)
+{
+ document->addMessage(source, type, level, message, lineNumber, sourceURL);
+}
+
+void SharedWorkerProxy::postConsoleMessageToWorkerObject(MessageSource source, MessageType type, MessageLevel level, const String& message, int lineNumber, const String& sourceURL)
+{
+ MutexLocker lock(m_workerDocumentsLock);
+ for (HashSet<Document*>::iterator iter = m_workerDocuments.begin(); iter != m_workerDocuments.end(); ++iter)
+ (*iter)->postTask(createCallbackTask(&postConsoleMessageTask, source, type, level, message, lineNumber, sourceURL));
+}
+
+void SharedWorkerProxy::workerContextClosed()
+{
+ if (isClosing())
+ return;
+ close();
+}
+
+void SharedWorkerProxy::workerContextDestroyed()
+{
+ // The proxy may be freed by this call, so do not reference it any further.
+ DefaultSharedWorkerRepository::instance().removeProxy(this);
+}
+
+void SharedWorkerProxy::addToWorkerDocuments(ScriptExecutionContext* context)
+{
+ // Nested workers are not yet supported, so passed-in context should always be a Document.
+ ASSERT(context->isDocument());
+ ASSERT(!isClosing());
+ MutexLocker lock(m_workerDocumentsLock);
+ Document* document = static_cast<Document*>(context);
+ m_workerDocuments.add(document);
+}
+
+void SharedWorkerProxy::documentDetached(Document* document)
+{
+ if (isClosing())
+ return;
+ // 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.
+ MutexLocker lock(m_workerDocumentsLock);
+ m_workerDocuments.remove(document);
+ if (!m_workerDocuments.size())
+ close();
+}
+
+void SharedWorkerProxy::close()
+{
+ ASSERT(!isClosing());
+ m_closing = true;
+ // Stop the worker thread - the proxy will stay around until we get workerThreadExited() notification.
+ if (m_thread)
+ m_thread->stop();
+}
+
+class SharedWorkerConnectTask : public ScriptExecutionContext::Task {
+public:
+ static PassOwnPtr<SharedWorkerConnectTask> create(PassOwnPtr<MessagePortChannel> channel)
+ {
+ return new SharedWorkerConnectTask(channel);
+ }
+
+private:
+ SharedWorkerConnectTask(PassOwnPtr<MessagePortChannel> channel)
+ : m_channel(channel)
+ {
+ }
+
+ virtual void performTask(ScriptExecutionContext* scriptContext)
+ {
+ RefPtr<MessagePort> port = MessagePort::create(*scriptContext);
+ port->entangle(m_channel.release());
+ ASSERT(scriptContext->isWorkerContext());
+ WorkerContext* workerContext = static_cast<WorkerContext*>(scriptContext);
+ // Since close() stops the thread event loop, this should not ever get called while closing.
+ ASSERT(!workerContext->isClosing());
+ ASSERT(workerContext->isSharedWorkerContext());
+ workerContext->toSharedWorkerContext()->dispatchEvent(createConnectEvent(port));
+ }
+
+ OwnPtr<MessagePortChannel> m_channel;
+};
+
+// Loads the script on behalf of a worker.
+class SharedWorkerScriptLoader : public RefCounted<SharedWorkerScriptLoader>, private WorkerScriptLoaderClient {
+public:
+ SharedWorkerScriptLoader(PassRefPtr<SharedWorker>, PassOwnPtr<MessagePortChannel>, PassRefPtr<SharedWorkerProxy>);
+ void load(const KURL&);
+
+private:
+ // WorkerScriptLoaderClient callback
+ virtual void notifyFinished();
+
+ RefPtr<SharedWorker> m_worker;
+ OwnPtr<MessagePortChannel> m_port;
+ RefPtr<SharedWorkerProxy> m_proxy;
+ OwnPtr<WorkerScriptLoader> m_scriptLoader;
+};
+
+SharedWorkerScriptLoader::SharedWorkerScriptLoader(PassRefPtr<SharedWorker> worker, PassOwnPtr<MessagePortChannel> port, PassRefPtr<SharedWorkerProxy> proxy)
+ : m_worker(worker)
+ , m_port(port)
+ , m_proxy(proxy)
+{
+}
+
+void SharedWorkerScriptLoader::load(const KURL& url)
+{
+ // Mark this object as active for the duration of the load.
+ m_scriptLoader = new WorkerScriptLoader(ResourceRequestBase::TargetIsSharedWorker);
+ m_scriptLoader->loadAsynchronously(m_worker->scriptExecutionContext(), url, DenyCrossOriginRequests, this);
+
+ // Stay alive (and keep the SharedWorker and JS wrapper alive) until the load finishes.
+ this->ref();
+ m_worker->setPendingActivity(m_worker.get());
+}
+
+void SharedWorkerScriptLoader::notifyFinished()
+{
+ // FIXME: This method is not guaranteed to be invoked if we are loading from WorkerContext (see comment for WorkerScriptLoaderClient::notifyFinished()).
+ // We need to address this before supporting nested workers.
+
+ // Hand off the just-loaded code to the repository to start up the worker thread.
+ if (m_scriptLoader->failed())
+ m_worker->dispatchEvent(Event::create(eventNames().errorEvent, false, true));
+ else {
+#if ENABLE(INSPECTOR)
+ if (InspectorController* inspector = m_worker->scriptExecutionContext()->inspectorController())
+ inspector->scriptImported(m_scriptLoader->identifier(), m_scriptLoader->script());
+#endif
+ DefaultSharedWorkerRepository::instance().workerScriptLoaded(*m_proxy, m_worker->scriptExecutionContext()->userAgent(m_scriptLoader->url()), m_scriptLoader->script(), m_port.release());
+ }
+ m_worker->unsetPendingActivity(m_worker.get());
+ this->deref(); // This frees this object - must be the last action in this function.
+}
+
+DefaultSharedWorkerRepository& DefaultSharedWorkerRepository::instance()
+{
+ AtomicallyInitializedStatic(DefaultSharedWorkerRepository*, instance = new DefaultSharedWorkerRepository);
+ return *instance;
+}
+
+void DefaultSharedWorkerRepository::workerScriptLoaded(SharedWorkerProxy& proxy, const String& userAgent, const String& workerScript, PassOwnPtr<MessagePortChannel> port)
+{
+ MutexLocker lock(m_lock);
+ if (proxy.isClosing())
+ return;
+
+ // Another loader may have already started up a thread for this proxy - if so, just send a connect to the pre-existing thread.
+ if (!proxy.thread()) {
+ RefPtr<SharedWorkerThread> thread = SharedWorkerThread::create(proxy.name(), proxy.url(), userAgent, workerScript, proxy, proxy);
+ proxy.setThread(thread);
+ thread->start();
+ }
+ proxy.thread()->runLoop().postTask(SharedWorkerConnectTask::create(port));
+}
+
+bool SharedWorkerRepository::isAvailable()
+{
+ // SharedWorkers are enabled on the default WebKit platform.
+ return true;
+}
+
+void SharedWorkerRepository::connect(PassRefPtr<SharedWorker> worker, PassOwnPtr<MessagePortChannel> port, const KURL& url, const String& name, ExceptionCode& ec)
+{
+ DefaultSharedWorkerRepository::instance().connectToWorker(worker, port, url, name, ec);
+}
+
+void SharedWorkerRepository::documentDetached(Document* document)
+{
+ DefaultSharedWorkerRepository::instance().documentDetached(document);
+}
+
+bool SharedWorkerRepository::hasSharedWorkers(Document* document)
+{
+ return DefaultSharedWorkerRepository::instance().hasSharedWorkers(document);
+}
+
+bool DefaultSharedWorkerRepository::hasSharedWorkers(Document* document)
+{
+ MutexLocker lock(m_lock);
+ for (unsigned i = 0; i < m_proxies.size(); i++) {
+ if (m_proxies[i]->isInWorkerDocuments(document))
+ return true;
+ }
+ return false;
+}
+
+void DefaultSharedWorkerRepository::removeProxy(SharedWorkerProxy* proxy)
+{
+ MutexLocker lock(m_lock);
+ for (unsigned i = 0; i < m_proxies.size(); i++) {
+ if (proxy == m_proxies[i].get()) {
+ m_proxies.remove(i);
+ return;
+ }
+ }
+}
+
+void DefaultSharedWorkerRepository::documentDetached(Document* document)
+{
+ MutexLocker lock(m_lock);
+ for (unsigned i = 0; i < m_proxies.size(); i++)
+ m_proxies[i]->documentDetached(document);
+}
+
+void DefaultSharedWorkerRepository::connectToWorker(PassRefPtr<SharedWorker> worker, PassOwnPtr<MessagePortChannel> port, const KURL& url, const String& name, ExceptionCode& ec)
+{
+ MutexLocker lock(m_lock);
+ ASSERT(worker->scriptExecutionContext()->securityOrigin()->canAccess(SecurityOrigin::create(url).get()));
+ // Fetch a proxy corresponding to this SharedWorker.
+ RefPtr<SharedWorkerProxy> proxy = getProxy(name, url);
+ proxy->addToWorkerDocuments(worker->scriptExecutionContext());
+ if (proxy->url() != url) {
+ // Proxy already existed under alternate URL - return an error.
+ ec = URL_MISMATCH_ERR;
+ return;
+ }
+ // If proxy is already running, just connect to it - otherwise, kick off a loader to load the script.
+ if (proxy->thread())
+ proxy->thread()->runLoop().postTask(SharedWorkerConnectTask::create(port));
+ else {
+ RefPtr<SharedWorkerScriptLoader> loader = adoptRef(new SharedWorkerScriptLoader(worker, port, proxy.release()));
+ loader->load(url);
+ }
+}
+
+// Creates a new SharedWorkerProxy or returns an existing one from the repository. Must only be called while the repository mutex is held.
+PassRefPtr<SharedWorkerProxy> DefaultSharedWorkerRepository::getProxy(const String& name, const KURL& url)
+{
+ // Look for an existing worker, and create one if it doesn't exist.
+ // Items in the cache are freed on another thread, so do a threadsafe copy of the URL before creating the origin,
+ // to make sure no references to external strings linger.
+ RefPtr<SecurityOrigin> origin = SecurityOrigin::create(KURL(ParsedURLString, url.string().threadsafeCopy()));
+ for (unsigned i = 0; i < m_proxies.size(); i++) {
+ if (!m_proxies[i]->isClosing() && m_proxies[i]->matches(name, origin, url))
+ return m_proxies[i];
+ }
+ // Proxy is not in the repository currently - create a new one.
+ RefPtr<SharedWorkerProxy> proxy = SharedWorkerProxy::create(name, url, origin.release());
+ m_proxies.append(proxy);
+ return proxy.release();
+}
+
+DefaultSharedWorkerRepository::DefaultSharedWorkerRepository()
+{
+}
+
+DefaultSharedWorkerRepository::~DefaultSharedWorkerRepository()
+{
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(SHARED_WORKERS)
diff --git a/Source/WebCore/workers/DefaultSharedWorkerRepository.h b/Source/WebCore/workers/DefaultSharedWorkerRepository.h
new file mode 100644
index 0000000..21e14a1
--- /dev/null
+++ b/Source/WebCore/workers/DefaultSharedWorkerRepository.h
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef DefaultSharedWorkerRepository_h
+#define DefaultSharedWorkerRepository_h
+
+#if ENABLE(SHARED_WORKERS)
+
+#include "ExceptionCode.h"
+#include <wtf/Forward.h>
+#include <wtf/HashMap.h>
+#include <wtf/Noncopyable.h>
+#include <wtf/PassOwnPtr.h>
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefPtr.h>
+#include <wtf/Threading.h>
+#include <wtf/text/StringHash.h>
+
+namespace WebCore {
+
+ class Document;
+ class KURL;
+ class MessagePortChannel;
+ class ScriptExecutionContext;
+ class SharedWorker;
+ class SharedWorkerProxy;
+
+ // Platform-specific implementation of the SharedWorkerRepository static interface.
+ class DefaultSharedWorkerRepository : public Noncopyable {
+ public:
+ // Invoked once the worker script has been loaded to fire up the worker thread.
+ void workerScriptLoaded(SharedWorkerProxy&, const String& userAgent, const String& workerScript, PassOwnPtr<MessagePortChannel>);
+
+ // Internal implementation of SharedWorkerRepository::connect()
+ void connectToWorker(PassRefPtr<SharedWorker>, PassOwnPtr<MessagePortChannel>, const KURL&, const String& name, ExceptionCode&);
+
+ // Notification that a document has been detached.
+ void documentDetached(Document*);
+
+ // Removes the passed SharedWorkerProxy from the repository.
+ void removeProxy(SharedWorkerProxy*);
+
+ bool hasSharedWorkers(Document*);
+
+ static DefaultSharedWorkerRepository& instance();
+ private:
+ DefaultSharedWorkerRepository();
+ ~DefaultSharedWorkerRepository();
+
+ PassRefPtr<SharedWorkerProxy> getProxy(const String& name, const KURL&);
+ // Mutex used to protect internal data structures.
+ Mutex m_lock;
+
+ // List of shared workers. Expectation is that there will be a limited number of shared workers, and so tracking them in a Vector is more efficient than nested HashMaps.
+ typedef Vector<RefPtr<SharedWorkerProxy> > SharedWorkerProxyRepository;
+ SharedWorkerProxyRepository m_proxies;
+ };
+
+} // namespace WebCore
+
+#endif // ENABLE(SHARED_WORKERS)
+
+#endif // DefaultSharedWorkerRepository_h
diff --git a/Source/WebCore/workers/SharedWorker.cpp b/Source/WebCore/workers/SharedWorker.cpp
new file mode 100644
index 0000000..997f9cd
--- /dev/null
+++ b/Source/WebCore/workers/SharedWorker.cpp
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ * Copyright (C) 2010 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#if ENABLE(SHARED_WORKERS)
+
+#include "SharedWorker.h"
+
+#include "InspectorController.h"
+#include "KURL.h"
+#include "MessageChannel.h"
+#include "MessagePort.h"
+#include "ScriptExecutionContext.h"
+#include "SharedWorkerRepository.h"
+
+namespace WebCore {
+
+inline SharedWorker::SharedWorker(ScriptExecutionContext* context)
+ : AbstractWorker(context)
+{
+}
+
+PassRefPtr<SharedWorker> SharedWorker::create(const String& url, const String& name, ScriptExecutionContext* context, ExceptionCode& ec)
+{
+ RefPtr<SharedWorker> worker = adoptRef(new SharedWorker(context));
+
+ RefPtr<MessageChannel> channel = MessageChannel::create(context);
+ worker->m_port = channel->port1();
+ OwnPtr<MessagePortChannel> remotePort = channel->port2()->disentangle(ec);
+ ASSERT(remotePort);
+
+ KURL scriptURL = worker->resolveURL(url, ec);
+ if (scriptURL.isEmpty())
+ return 0;
+
+ SharedWorkerRepository::connect(worker.get(), remotePort.release(), scriptURL, name, ec);
+
+#if ENABLE(INSPECTOR)
+ if (InspectorController* inspector = context->inspectorController())
+ inspector->didCreateWorker(worker->asID(), scriptURL.string(), true);
+#endif
+
+ return worker.release();
+}
+
+SharedWorker::~SharedWorker()
+{
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(SHARED_WORKERS)
diff --git a/Source/WebCore/workers/SharedWorker.h b/Source/WebCore/workers/SharedWorker.h
new file mode 100644
index 0000000..07aff19
--- /dev/null
+++ b/Source/WebCore/workers/SharedWorker.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ * Copyright (C) 2010 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef SharedWorker_h
+#define SharedWorker_h
+
+#include "AbstractWorker.h"
+
+#if ENABLE(SHARED_WORKERS)
+
+namespace WebCore {
+
+ class SharedWorker : public AbstractWorker {
+ public:
+ static PassRefPtr<SharedWorker> create(const String& url, const String& name, ScriptExecutionContext*, ExceptionCode&);
+ virtual ~SharedWorker();
+
+ MessagePort* port() const { return m_port.get(); }
+
+ private:
+ SharedWorker(ScriptExecutionContext*);
+
+ virtual SharedWorker* toSharedWorker() { return this; }
+
+ RefPtr<MessagePort> m_port;
+ };
+
+} // namespace WebCore
+
+#endif // ENABLE(SHARED_WORKERS)
+
+#endif // SharedWorker_h
diff --git a/Source/WebCore/workers/SharedWorker.idl b/Source/WebCore/workers/SharedWorker.idl
new file mode 100644
index 0000000..748adc3
--- /dev/null
+++ b/Source/WebCore/workers/SharedWorker.idl
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ * Copyright (C) 2010 Apple Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+module threads {
+
+ interface [
+ Conditional=SHARED_WORKERS,
+ CanBeConstructed,
+ CustomConstructFunction,
+ ConstructorParameters=2,
+ V8CustomConstructor,
+ CustomMarkFunction,
+ GenerateNativeConverter,
+ GenerateToJS
+ ] SharedWorker : AbstractWorker {
+ readonly attribute MessagePort port;
+ };
+
+}
diff --git a/Source/WebCore/workers/SharedWorkerContext.cpp b/Source/WebCore/workers/SharedWorkerContext.cpp
new file mode 100644
index 0000000..cd76e3b
--- /dev/null
+++ b/Source/WebCore/workers/SharedWorkerContext.cpp
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#if ENABLE(SHARED_WORKERS)
+
+#include "SharedWorkerContext.h"
+
+#include "DOMWindow.h"
+#include "EventNames.h"
+#include "MessageEvent.h"
+#include "NotImplemented.h"
+#include "SharedWorkerThread.h"
+
+namespace WebCore {
+
+PassRefPtr<MessageEvent> createConnectEvent(PassRefPtr<MessagePort> port)
+{
+ RefPtr<MessageEvent> event = MessageEvent::create(new MessagePortArray(1, port));
+ event->initEvent(eventNames().connectEvent, false, false);
+ return event;
+}
+
+SharedWorkerContext::SharedWorkerContext(const String& name, const KURL& url, const String& userAgent, SharedWorkerThread* thread)
+ : WorkerContext(url, userAgent, thread)
+ , m_name(name)
+{
+}
+
+SharedWorkerContext::~SharedWorkerContext()
+{
+}
+
+SharedWorkerThread* SharedWorkerContext::thread()
+{
+ return static_cast<SharedWorkerThread*>(Base::thread());
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(SHARED_WORKERS)
diff --git a/Source/WebCore/workers/SharedWorkerContext.h b/Source/WebCore/workers/SharedWorkerContext.h
new file mode 100644
index 0000000..59a7605
--- /dev/null
+++ b/Source/WebCore/workers/SharedWorkerContext.h
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef SharedWorkerContext_h
+#define SharedWorkerContext_h
+
+#if ENABLE(SHARED_WORKERS)
+
+#include "WorkerContext.h"
+
+namespace WebCore {
+
+ class MessageEvent;
+ class SharedWorkerThread;
+
+ class SharedWorkerContext : public WorkerContext {
+ public:
+ typedef WorkerContext Base;
+ static PassRefPtr<SharedWorkerContext> create(const String& name, const KURL& url, const String& userAgent, SharedWorkerThread* thread)
+ {
+ return adoptRef(new SharedWorkerContext(name, url, userAgent, thread));
+ }
+ virtual ~SharedWorkerContext();
+
+ virtual bool isSharedWorkerContext() const { return true; }
+
+ // EventTarget
+ virtual SharedWorkerContext* toSharedWorkerContext() { return this; }
+
+ // Setters/Getters for attributes in SharedWorkerContext.idl
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(connect);
+ String name() const { return m_name; }
+
+ SharedWorkerThread* thread();
+ private:
+ SharedWorkerContext(const String& name, const KURL&, const String&, SharedWorkerThread*);
+ String m_name;
+ };
+
+ PassRefPtr<MessageEvent> createConnectEvent(PassRefPtr<MessagePort>);
+
+} // namespace WebCore
+
+#endif // ENABLE(SHARED_WORKERS)
+
+#endif // SharedWorkerContext_h
diff --git a/Source/WebCore/workers/SharedWorkerContext.idl b/Source/WebCore/workers/SharedWorkerContext.idl
new file mode 100644
index 0000000..9d01f4f
--- /dev/null
+++ b/Source/WebCore/workers/SharedWorkerContext.idl
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+module threads {
+
+ interface [
+ Conditional=SHARED_WORKERS,
+ ExtendsDOMGlobalObject,
+ IsWorkerContext,
+ GenerateNativeConverter,
+ NoStaticTables,
+ OmitConstructor
+ ] SharedWorkerContext : WorkerContext {
+
+ readonly attribute DOMString name;
+ attribute EventListener onconnect;
+
+ };
+
+}
diff --git a/Source/WebCore/workers/SharedWorkerRepository.h b/Source/WebCore/workers/SharedWorkerRepository.h
new file mode 100644
index 0000000..d654070
--- /dev/null
+++ b/Source/WebCore/workers/SharedWorkerRepository.h
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef SharedWorkerRepository_h
+#define SharedWorkerRepository_h
+
+#if ENABLE(SHARED_WORKERS)
+
+#include "ExceptionCode.h"
+#include <wtf/Forward.h>
+#include <wtf/PassOwnPtr.h>
+#include <wtf/PassRefPtr.h>
+
+namespace WebCore {
+
+ class Document;
+ class KURL;
+ class MessagePortChannel;
+ class SharedWorker;
+
+ // Interface to a repository which manages references to the set of active shared workers.
+ class SharedWorkerRepository {
+ public:
+ // Returns true if the platform supports SharedWorkers, otherwise false.
+ static bool isAvailable();
+
+ // Connects the passed SharedWorker object with the specified worker thread, creating a new thread if necessary.
+ static void connect(PassRefPtr<SharedWorker>, PassOwnPtr<MessagePortChannel>, const KURL&, const String& name, ExceptionCode&);
+
+ // Invoked when a document has been detached.
+ static void documentDetached(Document*);
+
+ // Returns true if the passed document is associated with any SharedWorkers.
+ static bool hasSharedWorkers(Document*);
+ private:
+ SharedWorkerRepository() { }
+ };
+
+} // namespace WebCore
+
+#endif // ENABLE(SHARED_WORKERS)
+
+#endif // SharedWorkerRepository_h
diff --git a/Source/WebCore/workers/SharedWorkerThread.cpp b/Source/WebCore/workers/SharedWorkerThread.cpp
new file mode 100644
index 0000000..e59df4f
--- /dev/null
+++ b/Source/WebCore/workers/SharedWorkerThread.cpp
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#if ENABLE(SHARED_WORKERS)
+
+#include "SharedWorkerThread.h"
+
+#include "SharedWorkerContext.h"
+
+namespace WebCore {
+
+PassRefPtr<SharedWorkerThread> SharedWorkerThread::create(const String& name, const KURL& scriptURL, const String& userAgent, const String& sourceCode, WorkerLoaderProxy& workerLoaderProxy, WorkerReportingProxy& workerReportingProxy)
+{
+ return adoptRef(new SharedWorkerThread(name, scriptURL, userAgent, sourceCode, workerLoaderProxy, workerReportingProxy));
+}
+
+SharedWorkerThread::SharedWorkerThread(const String& name, const KURL& url, const String& userAgent, const String& sourceCode, WorkerLoaderProxy& workerLoaderProxy, WorkerReportingProxy& workerReportingProxy)
+ : WorkerThread(url, userAgent, sourceCode, workerLoaderProxy, workerReportingProxy)
+ , m_name(name.crossThreadString())
+{
+}
+
+SharedWorkerThread::~SharedWorkerThread()
+{
+}
+
+PassRefPtr<WorkerContext> SharedWorkerThread::createWorkerContext(const KURL& url, const String& userAgent)
+{
+ return SharedWorkerContext::create(m_name, url, userAgent, this);
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(SHARED_WORKERS)
diff --git a/Source/WebCore/workers/SharedWorkerThread.h b/Source/WebCore/workers/SharedWorkerThread.h
new file mode 100644
index 0000000..d96fd2a
--- /dev/null
+++ b/Source/WebCore/workers/SharedWorkerThread.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef SharedWorkerThread_h
+#define SharedWorkerThread_h
+
+#if ENABLE(SHARED_WORKERS)
+
+#include "WorkerThread.h"
+
+namespace WebCore {
+
+ class SharedWorkerThread : public WorkerThread {
+ public:
+ static PassRefPtr<SharedWorkerThread> create(const String& name, const KURL&, const String& userAgent, const String& sourceCode, WorkerLoaderProxy&, WorkerReportingProxy&);
+ ~SharedWorkerThread();
+
+ protected:
+ virtual PassRefPtr<WorkerContext> createWorkerContext(const KURL&, const String&);
+
+ private:
+ SharedWorkerThread(const String& name, const KURL&, const String& userAgent, const String& sourceCode, WorkerLoaderProxy&, WorkerReportingProxy&);
+
+ String m_name;
+ };
+} // namespace WebCore
+
+#endif // ENABLE(SHARED_WORKERS)
+
+#endif // SharedWorkerThread_h
diff --git a/Source/WebCore/workers/Worker.cpp b/Source/WebCore/workers/Worker.cpp
new file mode 100644
index 0000000..32ec997
--- /dev/null
+++ b/Source/WebCore/workers/Worker.cpp
@@ -0,0 +1,150 @@
+/*
+ * Copyright (C) 2008, 2010 Apple Inc. All Rights Reserved.
+ * Copyright (C) 2009 Google Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "config.h"
+
+#if ENABLE(WORKERS)
+
+#include "Worker.h"
+
+#include "DOMWindow.h"
+#include "CachedResourceLoader.h"
+#include "Document.h"
+#include "EventException.h"
+#include "EventListener.h"
+#include "EventNames.h"
+#include "ExceptionCode.h"
+#include "Frame.h"
+#include "FrameLoader.h"
+#include "InspectorController.h"
+#include "MessageEvent.h"
+#include "TextEncoding.h"
+#include "WorkerContextProxy.h"
+#include "WorkerScriptLoader.h"
+#include "WorkerThread.h"
+#include <wtf/MainThread.h>
+
+namespace WebCore {
+
+inline Worker::Worker(ScriptExecutionContext* context)
+ : AbstractWorker(context)
+ , m_contextProxy(WorkerContextProxy::create(this))
+{
+}
+
+PassRefPtr<Worker> Worker::create(const String& url, ScriptExecutionContext* context, ExceptionCode& ec)
+{
+ RefPtr<Worker> worker = adoptRef(new Worker(context));
+
+ KURL scriptURL = worker->resolveURL(url, ec);
+ if (scriptURL.isEmpty())
+ return 0;
+
+ worker->m_scriptLoader = adoptPtr(new WorkerScriptLoader(ResourceRequestBase::TargetIsWorker));
+ worker->m_scriptLoader->loadAsynchronously(context, scriptURL, DenyCrossOriginRequests, worker.get());
+
+ // The worker context does not exist while loading, so we must ensure that the worker object is not collected, nor are its event listeners.
+ worker->setPendingActivity(worker.get());
+
+#if ENABLE(INSPECTOR)
+ if (InspectorController* inspector = context->inspectorController())
+ inspector->didCreateWorker(worker->asID(), scriptURL.string(), false);
+#endif
+
+ return worker.release();
+}
+
+Worker::~Worker()
+{
+ ASSERT(isMainThread());
+ ASSERT(scriptExecutionContext()); // The context is protected by worker context proxy, so it cannot be destroyed while a Worker exists.
+ m_contextProxy->workerObjectDestroyed();
+}
+
+// FIXME: remove this when we update the ObjC bindings (bug #28774).
+void Worker::postMessage(PassRefPtr<SerializedScriptValue> message, MessagePort* port, ExceptionCode& ec)
+{
+ MessagePortArray ports;
+ if (port)
+ ports.append(port);
+ postMessage(message, &ports, ec);
+}
+
+void Worker::postMessage(PassRefPtr<SerializedScriptValue> message, ExceptionCode& ec)
+{
+ postMessage(message, static_cast<MessagePortArray*>(0), ec);
+}
+
+void Worker::postMessage(PassRefPtr<SerializedScriptValue> message, const MessagePortArray* ports, ExceptionCode& ec)
+{
+ // Disentangle the port in preparation for sending it to the remote context.
+ OwnPtr<MessagePortChannelArray> channels = MessagePort::disentanglePorts(ports, ec);
+ if (ec)
+ return;
+ m_contextProxy->postMessageToWorkerContext(message, channels.release());
+}
+
+void Worker::terminate()
+{
+ m_contextProxy->terminateWorkerContext();
+}
+
+bool Worker::canSuspend() const
+{
+ // FIXME: It is not currently possible to suspend a worker, so pages with workers can not go into page cache.
+ return false;
+}
+
+void Worker::stop()
+{
+ terminate();
+}
+
+bool Worker::hasPendingActivity() const
+{
+ return m_contextProxy->hasPendingActivity() || ActiveDOMObject::hasPendingActivity();
+}
+
+void Worker::notifyFinished()
+{
+ if (m_scriptLoader->failed())
+ dispatchEvent(Event::create(eventNames().errorEvent, false, true));
+ else {
+ m_contextProxy->startWorkerContext(m_scriptLoader->url(), scriptExecutionContext()->userAgent(m_scriptLoader->url()), m_scriptLoader->script());
+#if ENABLE(INSPECTOR)
+ if (InspectorController* inspector = scriptExecutionContext()->inspectorController())
+ inspector->scriptImported(m_scriptLoader->identifier(), m_scriptLoader->script());
+#endif
+ }
+ m_scriptLoader = 0;
+
+ unsetPendingActivity(this);
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(WORKERS)
diff --git a/Source/WebCore/workers/Worker.h b/Source/WebCore/workers/Worker.h
new file mode 100644
index 0000000..0e673ac
--- /dev/null
+++ b/Source/WebCore/workers/Worker.h
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2008, 2010 Apple Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef Worker_h
+#define Worker_h
+
+#if ENABLE(WORKERS)
+
+#include "AbstractWorker.h"
+#include "ActiveDOMObject.h"
+#include "EventListener.h"
+#include "EventNames.h"
+#include "EventTarget.h"
+#include "MessagePort.h"
+#include "WorkerScriptLoaderClient.h"
+#include <wtf/Forward.h>
+#include <wtf/OwnPtr.h>
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefCounted.h>
+#include <wtf/RefPtr.h>
+#include <wtf/text/AtomicStringHash.h>
+
+namespace WebCore {
+
+ class ScriptExecutionContext;
+ class WorkerContextProxy;
+ class WorkerScriptLoader;
+
+ typedef int ExceptionCode;
+
+ class Worker : public AbstractWorker, private WorkerScriptLoaderClient {
+ public:
+ static PassRefPtr<Worker> create(const String& url, ScriptExecutionContext*, ExceptionCode&);
+ virtual ~Worker();
+
+ virtual Worker* toWorker() { return this; }
+
+ void postMessage(PassRefPtr<SerializedScriptValue> message, ExceptionCode&);
+ void postMessage(PassRefPtr<SerializedScriptValue> message, const MessagePortArray*, ExceptionCode&);
+ // FIXME: remove this when we update the ObjC bindings (bug #28774).
+ void postMessage(PassRefPtr<SerializedScriptValue> message, MessagePort*, ExceptionCode&);
+
+ void terminate();
+
+ virtual bool canSuspend() const;
+ virtual void stop();
+ virtual bool hasPendingActivity() const;
+
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(message);
+
+ private:
+ Worker(ScriptExecutionContext*);
+
+ virtual void notifyFinished();
+
+ virtual void refEventTarget() { ref(); }
+ virtual void derefEventTarget() { deref(); }
+
+ OwnPtr<WorkerScriptLoader> m_scriptLoader;
+ WorkerContextProxy* m_contextProxy; // The proxy outlives the worker to perform thread shutdown.
+ };
+
+} // namespace WebCore
+
+#endif // ENABLE(WORKERS)
+
+#endif // Worker_h
diff --git a/Source/WebCore/workers/Worker.idl b/Source/WebCore/workers/Worker.idl
new file mode 100644
index 0000000..e53de93
--- /dev/null
+++ b/Source/WebCore/workers/Worker.idl
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2008, 2010 Apple Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+module threads {
+
+ interface [
+ Conditional=WORKERS,
+ CanBeConstructed,
+ CustomConstructFunction,
+ ConstructorParameters=1,
+ V8CustomConstructor,
+ GenerateNativeConverter,
+ GenerateToJS
+ ] Worker : AbstractWorker {
+
+ attribute EventListener onmessage;
+
+#if defined(LANGUAGE_JAVASCRIPT) && LANGUAGE_JAVASCRIPT
+ [Custom] void postMessage(in SerialisedScriptValue message, in [Optional] Array messagePorts)
+ raises(DOMException);
+#else
+ // There's no good way to expose an array via the ObjC bindings, so for now just allow passing in a single port.
+ void postMessage(in SerializedScriptValue message, in [Optional] MessagePort messagePort)
+ raises(DOMException);
+#endif
+
+ void terminate();
+ };
+
+}
diff --git a/Source/WebCore/workers/WorkerContext.cpp b/Source/WebCore/workers/WorkerContext.cpp
new file mode 100644
index 0000000..345e5b7
--- /dev/null
+++ b/Source/WebCore/workers/WorkerContext.cpp
@@ -0,0 +1,444 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All Rights Reserved.
+ * Copyright (C) 2009 Google Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "config.h"
+
+#if ENABLE(WORKERS)
+
+#include "WorkerContext.h"
+
+#include "AbstractDatabase.h"
+#include "ActiveDOMObject.h"
+#include "Database.h"
+#include "DatabaseCallback.h"
+#include "DatabaseSync.h"
+#include "DatabaseTracker.h"
+#include "DOMTimer.h"
+#include "DOMWindow.h"
+#include "ErrorEvent.h"
+#include "Event.h"
+#include "EventException.h"
+#include "InspectorController.h"
+#include "KURL.h"
+#include "MessagePort.h"
+#include "NotImplemented.h"
+#include "ScriptSourceCode.h"
+#include "ScriptValue.h"
+#include "SecurityOrigin.h"
+#include "WorkerLocation.h"
+#include "WorkerNavigator.h"
+#include "WorkerObjectProxy.h"
+#include "WorkerScriptLoader.h"
+#include "WorkerThread.h"
+#include "WorkerThreadableLoader.h"
+#include "XMLHttpRequestException.h"
+#include <wtf/RefPtr.h>
+#include <wtf/UnusedParam.h>
+
+#if ENABLE(NOTIFICATIONS)
+#include "NotificationCenter.h"
+#endif
+
+#if ENABLE(FILE_SYSTEM)
+#include "AsyncFileSystem.h"
+#include "DOMFileSystem.h"
+#include "DOMFileSystemSync.h"
+#include "ErrorCallback.h"
+#include "FileError.h"
+#include "FileException.h"
+#include "FileSystemCallback.h"
+#include "FileSystemCallbacks.h"
+#include "LocalFileSystem.h"
+#include "SyncCallbackHelper.h"
+#endif
+
+namespace WebCore {
+
+class CloseWorkerContextTask : public ScriptExecutionContext::Task {
+public:
+ static PassOwnPtr<CloseWorkerContextTask> create()
+ {
+ return new CloseWorkerContextTask;
+ }
+
+ virtual void performTask(ScriptExecutionContext *context)
+ {
+ ASSERT(context->isWorkerContext());
+ WorkerContext* workerContext = static_cast<WorkerContext*>(context);
+ // Notify parent that this context is closed. Parent is responsible for calling WorkerThread::stop().
+ workerContext->thread()->workerReportingProxy().workerContextClosed();
+ }
+
+ virtual bool isCleanupTask() const { return true; }
+};
+
+WorkerContext::WorkerContext(const KURL& url, const String& userAgent, WorkerThread* thread)
+ : m_url(url)
+ , m_userAgent(userAgent)
+ , m_script(new WorkerScriptController(this))
+ , m_thread(thread)
+ , m_closing(false)
+ , m_reportingException(false)
+{
+ setSecurityOrigin(SecurityOrigin::create(url));
+}
+
+WorkerContext::~WorkerContext()
+{
+ ASSERT(currentThread() == thread()->threadID());
+#if ENABLE(NOTIFICATIONS)
+ m_notifications.clear();
+#endif
+
+ // Make sure we have no observers.
+ notifyObserversOfStop();
+
+ // Notify proxy that we are going away. This can free the WorkerThread object, so do not access it after this.
+ thread()->workerReportingProxy().workerContextDestroyed();
+}
+
+ScriptExecutionContext* WorkerContext::scriptExecutionContext() const
+{
+ return const_cast<WorkerContext*>(this);
+}
+
+const KURL& WorkerContext::virtualURL() const
+{
+ return m_url;
+}
+
+KURL WorkerContext::virtualCompleteURL(const String& url) const
+{
+ return completeURL(url);
+}
+
+KURL WorkerContext::completeURL(const String& url) const
+{
+ // Always return a null URL when passed a null string.
+ // FIXME: Should we change the KURL constructor to have this behavior?
+ if (url.isNull())
+ return KURL();
+ // Always use UTF-8 in Workers.
+ return KURL(m_url, url);
+}
+
+String WorkerContext::userAgent(const KURL&) const
+{
+ return m_userAgent;
+}
+
+WorkerLocation* WorkerContext::location() const
+{
+ if (!m_location)
+ m_location = WorkerLocation::create(m_url);
+ return m_location.get();
+}
+
+void WorkerContext::close()
+{
+ if (m_closing)
+ return;
+
+ m_closing = true;
+ // Let current script run to completion but prevent future script evaluations.
+ m_script->forbidExecution(WorkerScriptController::LetRunningScriptFinish);
+ postTask(CloseWorkerContextTask::create());
+}
+
+WorkerNavigator* WorkerContext::navigator() const
+{
+ if (!m_navigator)
+ m_navigator = WorkerNavigator::create(m_userAgent);
+ return m_navigator.get();
+}
+
+bool WorkerContext::hasPendingActivity() const
+{
+ ActiveDOMObjectsMap& activeObjects = activeDOMObjects();
+ ActiveDOMObjectsMap::const_iterator activeObjectsEnd = activeObjects.end();
+ for (ActiveDOMObjectsMap::const_iterator iter = activeObjects.begin(); iter != activeObjectsEnd; ++iter) {
+ if (iter->first->hasPendingActivity())
+ return true;
+ }
+
+ // Keep the worker active as long as there is a MessagePort with pending activity or that is remotely entangled.
+ HashSet<MessagePort*>::const_iterator messagePortsEnd = messagePorts().end();
+ for (HashSet<MessagePort*>::const_iterator iter = messagePorts().begin(); iter != messagePortsEnd; ++iter) {
+ if ((*iter)->hasPendingActivity() || ((*iter)->isEntangled() && !(*iter)->locallyEntangledPort()))
+ return true;
+ }
+
+ return false;
+}
+
+void WorkerContext::postTask(PassOwnPtr<Task> task)
+{
+ thread()->runLoop().postTask(task);
+}
+
+int WorkerContext::setTimeout(PassOwnPtr<ScheduledAction> action, int timeout)
+{
+ return DOMTimer::install(scriptExecutionContext(), action, timeout, true);
+}
+
+void WorkerContext::clearTimeout(int timeoutId)
+{
+ DOMTimer::removeById(scriptExecutionContext(), timeoutId);
+}
+
+int WorkerContext::setInterval(PassOwnPtr<ScheduledAction> action, int timeout)
+{
+ return DOMTimer::install(scriptExecutionContext(), action, timeout, false);
+}
+
+void WorkerContext::clearInterval(int timeoutId)
+{
+ DOMTimer::removeById(scriptExecutionContext(), timeoutId);
+}
+
+void WorkerContext::importScripts(const Vector<String>& urls, ExceptionCode& ec)
+{
+ ec = 0;
+ Vector<String>::const_iterator urlsEnd = urls.end();
+ Vector<KURL> completedURLs;
+ for (Vector<String>::const_iterator it = urls.begin(); it != urlsEnd; ++it) {
+ const KURL& url = scriptExecutionContext()->completeURL(*it);
+ if (!url.isValid()) {
+ ec = SYNTAX_ERR;
+ return;
+ }
+ completedURLs.append(url);
+ }
+ Vector<KURL>::const_iterator end = completedURLs.end();
+
+ for (Vector<KURL>::const_iterator it = completedURLs.begin(); it != end; ++it) {
+ WorkerScriptLoader scriptLoader(ResourceRequestBase::TargetIsScript);
+ scriptLoader.loadSynchronously(scriptExecutionContext(), *it, AllowCrossOriginRequests);
+
+ // If the fetching attempt failed, throw a NETWORK_ERR exception and abort all these steps.
+ if (scriptLoader.failed()) {
+ ec = XMLHttpRequestException::NETWORK_ERR;
+ return;
+ }
+
+#if ENABLE(INSPECTOR)
+ if (InspectorController* inspector = scriptExecutionContext()->inspectorController())
+ inspector->scriptImported(scriptLoader.identifier(), scriptLoader.script());
+#endif
+
+ ScriptValue exception;
+ m_script->evaluate(ScriptSourceCode(scriptLoader.script(), *it), &exception);
+ if (!exception.hasNoValue()) {
+ m_script->setException(exception);
+ return;
+ }
+ }
+}
+
+void WorkerContext::reportException(const String& errorMessage, int lineNumber, const String& sourceURL)
+{
+ bool errorHandled = false;
+ if (!m_reportingException) {
+ if (onerror()) {
+ m_reportingException = true;
+ RefPtr<ErrorEvent> errorEvent(ErrorEvent::create(errorMessage, sourceURL, lineNumber));
+ onerror()->handleEvent(this, errorEvent.get());
+ errorHandled = errorEvent->defaultPrevented();
+ m_reportingException = false;
+ }
+ }
+ if (!errorHandled)
+ thread()->workerReportingProxy().postExceptionToWorkerObject(errorMessage, lineNumber, sourceURL);
+}
+
+void WorkerContext::addMessage(MessageSource source, MessageType type, MessageLevel level, const String& message, unsigned lineNumber, const String& sourceURL)
+{
+ thread()->workerReportingProxy().postConsoleMessageToWorkerObject(source, type, level, message, lineNumber, sourceURL);
+}
+
+#if ENABLE(NOTIFICATIONS)
+NotificationCenter* WorkerContext::webkitNotifications() const
+{
+ if (!m_notifications)
+ m_notifications = NotificationCenter::create(scriptExecutionContext(), m_thread->getNotificationPresenter());
+ return m_notifications.get();
+}
+#endif
+
+#if ENABLE(DATABASE)
+PassRefPtr<Database> WorkerContext::openDatabase(const String& name, const String& version, const String& displayName, unsigned long estimatedSize, PassRefPtr<DatabaseCallback> creationCallback, ExceptionCode& ec)
+{
+ if (!securityOrigin()->canAccessDatabase() || !AbstractDatabase::isAvailable()) {
+ ec = SECURITY_ERR;
+ return 0;
+ }
+
+ return Database::openDatabase(this, name, version, displayName, estimatedSize, creationCallback, ec);
+}
+
+void WorkerContext::databaseExceededQuota(const String&)
+{
+#if !PLATFORM(CHROMIUM)
+ // FIXME: This needs a real implementation; this is a temporary solution for testing.
+ const unsigned long long defaultQuota = 5 * 1024 * 1024;
+ DatabaseTracker::tracker().setQuota(securityOrigin(), defaultQuota);
+#endif
+}
+
+PassRefPtr<DatabaseSync> WorkerContext::openDatabaseSync(const String& name, const String& version, const String& displayName, unsigned long estimatedSize, PassRefPtr<DatabaseCallback> creationCallback, ExceptionCode& ec)
+{
+ if (!securityOrigin()->canAccessDatabase() || !AbstractDatabase::isAvailable()) {
+ ec = SECURITY_ERR;
+ return 0;
+ }
+
+ return DatabaseSync::openDatabaseSync(this, name, version, displayName, estimatedSize, creationCallback, ec);
+}
+#endif
+
+bool WorkerContext::isContextThread() const
+{
+ return currentThread() == thread()->threadID();
+}
+
+bool WorkerContext::isJSExecutionTerminated() const
+{
+ return m_script->isExecutionForbidden();
+}
+
+EventTargetData* WorkerContext::eventTargetData()
+{
+ return &m_eventTargetData;
+}
+
+EventTargetData* WorkerContext::ensureEventTargetData()
+{
+ return &m_eventTargetData;
+}
+
+#if ENABLE(BLOB)
+String WorkerContext::createObjectURL(Blob* blob)
+{
+ return scriptExecutionContext()->createPublicBlobURL(blob).string();
+}
+
+void WorkerContext::revokeObjectURL(const String& blobURLString)
+{
+ scriptExecutionContext()->revokePublicBlobURL(KURL(ParsedURLString, blobURLString));
+}
+#endif
+
+#if ENABLE(FILE_SYSTEM)
+void WorkerContext::requestFileSystem(int type, long long size, PassRefPtr<FileSystemCallback> successCallback, PassRefPtr<ErrorCallback> errorCallback)
+{
+ if (!AsyncFileSystem::isAvailable() || !securityOrigin()->canAccessFileSystem()) {
+ DOMFileSystem::scheduleCallback(this, errorCallback, FileError::create(FileError::SECURITY_ERR));
+ return;
+ }
+
+ AsyncFileSystem::Type fileSystemType = static_cast<AsyncFileSystem::Type>(type);
+ if (fileSystemType != AsyncFileSystem::Temporary && fileSystemType != AsyncFileSystem::Persistent) {
+ DOMFileSystem::scheduleCallback(this, errorCallback, FileError::create(FileError::INVALID_MODIFICATION_ERR));
+ return;
+ }
+
+ LocalFileSystem::localFileSystem().requestFileSystem(this, fileSystemType, size, FileSystemCallbacks::create(successCallback, errorCallback, this), false);
+}
+
+PassRefPtr<DOMFileSystemSync> WorkerContext::requestFileSystemSync(int type, long long size, ExceptionCode& ec)
+{
+ ec = 0;
+ if (!AsyncFileSystem::isAvailable() || !securityOrigin()->canAccessFileSystem()) {
+ ec = FileException::SECURITY_ERR;
+ return 0;
+ }
+
+ AsyncFileSystem::Type fileSystemType = static_cast<AsyncFileSystem::Type>(type);
+ if (fileSystemType != AsyncFileSystem::Temporary && fileSystemType != AsyncFileSystem::Persistent) {
+ ec = FileException::INVALID_MODIFICATION_ERR;
+ return 0;
+ }
+
+ FileSystemSyncCallbackHelper helper;
+ LocalFileSystem::localFileSystem().requestFileSystem(this, fileSystemType, size, FileSystemCallbacks::create(helper.successCallback(), helper.errorCallback(), this), true);
+ return helper.getResult(ec);
+}
+
+COMPILE_ASSERT(static_cast<int>(WorkerContext::TEMPORARY) == static_cast<int>(AsyncFileSystem::Temporary), enum_mismatch);
+COMPILE_ASSERT(static_cast<int>(WorkerContext::PERSISTENT) == static_cast<int>(AsyncFileSystem::Persistent), enum_mismatch);
+#endif
+
+WorkerContext::Observer::Observer(WorkerContext* context)
+ : m_context(context)
+{
+ ASSERT(m_context && m_context->isContextThread());
+ m_context->registerObserver(this);
+}
+
+WorkerContext::Observer::~Observer()
+{
+ if (!m_context)
+ return;
+ ASSERT(m_context->isContextThread());
+ m_context->unregisterObserver(this);
+}
+
+void WorkerContext::Observer::stopObserving()
+{
+ if (!m_context)
+ return;
+ ASSERT(m_context->isContextThread());
+ m_context->unregisterObserver(this);
+ m_context = 0;
+}
+
+void WorkerContext::registerObserver(Observer* observer)
+{
+ ASSERT(observer);
+ m_workerObservers.add(observer);
+}
+
+void WorkerContext::unregisterObserver(Observer* observer)
+{
+ ASSERT(observer);
+ m_workerObservers.remove(observer);
+}
+
+void WorkerContext::notifyObserversOfStop()
+{
+ HashSet<Observer*>::iterator iter = m_workerObservers.begin();
+ while (iter != m_workerObservers.end()) {
+ WorkerContext::Observer* observer = *iter;
+ observer->stopObserving();
+ observer->notifyStop();
+ iter = m_workerObservers.begin();
+ }
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(WORKERS)
diff --git a/Source/WebCore/workers/WorkerContext.h b/Source/WebCore/workers/WorkerContext.h
new file mode 100644
index 0000000..7b6c9a2
--- /dev/null
+++ b/Source/WebCore/workers/WorkerContext.h
@@ -0,0 +1,200 @@
+/*
+ * Copyright (C) 2008, 2009 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef WorkerContext_h
+#define WorkerContext_h
+
+#if ENABLE(WORKERS)
+
+#include "EventListener.h"
+#include "EventNames.h"
+#include "EventTarget.h"
+#include "ScriptExecutionContext.h"
+#include "WorkerScriptController.h"
+#include <wtf/Assertions.h>
+#include <wtf/HashMap.h>
+#include <wtf/OwnPtr.h>
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefCounted.h>
+#include <wtf/RefPtr.h>
+#include <wtf/text/AtomicStringHash.h>
+
+namespace WebCore {
+
+ class Blob;
+ class DOMFileSystemSync;
+ class Database;
+ class DatabaseCallback;
+ class DatabaseSync;
+ class ErrorCallback;
+ class FileSystemCallback;
+ class NotificationCenter;
+ class ScheduledAction;
+ class WorkerLocation;
+ class WorkerNavigator;
+ class WorkerThread;
+
+ class WorkerContext : public RefCounted<WorkerContext>, public ScriptExecutionContext, public EventTarget {
+ public:
+ virtual ~WorkerContext();
+
+ virtual bool isWorkerContext() const { return true; }
+
+ virtual ScriptExecutionContext* scriptExecutionContext() const;
+
+ virtual bool isSharedWorkerContext() const { return false; }
+ virtual bool isDedicatedWorkerContext() const { return false; }
+
+ const KURL& url() const { return m_url; }
+ KURL completeURL(const String&) const;
+
+ virtual String userAgent(const KURL&) const;
+
+ WorkerScriptController* script() { return m_script.get(); }
+ void clearScript() { m_script.clear(); }
+
+ WorkerThread* thread() const { return m_thread; }
+
+ bool hasPendingActivity() const;
+
+ virtual void postTask(PassOwnPtr<Task>); // Executes the task on context's thread asynchronously.
+
+ // WorkerGlobalScope
+ WorkerContext* self() { return this; }
+ WorkerLocation* location() const;
+ void close();
+
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(error);
+
+ // WorkerUtils
+ virtual void importScripts(const Vector<String>& urls, ExceptionCode&);
+ WorkerNavigator* navigator() const;
+
+ // Timers
+ int setTimeout(PassOwnPtr<ScheduledAction>, int timeout);
+ void clearTimeout(int timeoutId);
+ int setInterval(PassOwnPtr<ScheduledAction>, int timeout);
+ void clearInterval(int timeoutId);
+
+ // ScriptExecutionContext
+ virtual void reportException(const String& errorMessage, int lineNumber, const String& sourceURL);
+ virtual void addMessage(MessageSource, MessageType, MessageLevel, const String& message, unsigned lineNumber, const String& sourceURL);
+
+#if ENABLE(NOTIFICATIONS)
+ NotificationCenter* webkitNotifications() const;
+#endif
+
+#if ENABLE(DATABASE)
+ // HTML 5 client-side database
+ PassRefPtr<Database> openDatabase(const String& name, const String& version, const String& displayName, unsigned long estimatedSize, PassRefPtr<DatabaseCallback> creationCallback, ExceptionCode&);
+ PassRefPtr<DatabaseSync> openDatabaseSync(const String& name, const String& version, const String& displayName, unsigned long estimatedSize, PassRefPtr<DatabaseCallback> creationCallback, ExceptionCode&);
+
+ // Not implemented yet.
+ virtual bool allowDatabaseAccess() const { return true; }
+ // Not implemented for real yet.
+ virtual void databaseExceededQuota(const String&);
+#endif
+ virtual bool isContextThread() const;
+ virtual bool isJSExecutionTerminated() const;
+
+#if ENABLE(BLOB)
+ String createObjectURL(Blob*);
+ void revokeObjectURL(const String&);
+#endif
+
+#if ENABLE(FILE_SYSTEM)
+ enum FileSystemType {
+ TEMPORARY,
+ PERSISTENT,
+ };
+ void requestFileSystem(int type, long long size, PassRefPtr<FileSystemCallback>, PassRefPtr<ErrorCallback>);
+ PassRefPtr<DOMFileSystemSync> requestFileSystemSync(int type, long long size, ExceptionCode&);
+#endif
+
+ // These methods are used for GC marking. See JSWorkerContext::markChildren(MarkStack&) in
+ // JSWorkerContextCustom.cpp.
+ WorkerNavigator* optionalNavigator() const { return m_navigator.get(); }
+ WorkerLocation* optionalLocation() const { return m_location.get(); }
+
+ using RefCounted<WorkerContext>::ref;
+ using RefCounted<WorkerContext>::deref;
+
+ bool isClosing() { return m_closing; }
+
+ // An observer interface to be notified when the worker thread is getting stopped.
+ class Observer : public Noncopyable {
+ public:
+ Observer(WorkerContext*);
+ virtual ~Observer();
+ virtual void notifyStop() = 0;
+ void stopObserving();
+ private:
+ WorkerContext* m_context;
+ };
+ friend class Observer;
+ void registerObserver(Observer*);
+ void unregisterObserver(Observer*);
+ void notifyObserversOfStop();
+
+ protected:
+ WorkerContext(const KURL&, const String&, WorkerThread*);
+
+ private:
+ virtual void refScriptExecutionContext() { ref(); }
+ virtual void derefScriptExecutionContext() { deref(); }
+
+ virtual void refEventTarget() { ref(); }
+ virtual void derefEventTarget() { deref(); }
+ virtual EventTargetData* eventTargetData();
+ virtual EventTargetData* ensureEventTargetData();
+
+ virtual const KURL& virtualURL() const;
+ virtual KURL virtualCompleteURL(const String&) const;
+
+ KURL m_url;
+ String m_userAgent;
+
+ mutable RefPtr<WorkerLocation> m_location;
+ mutable RefPtr<WorkerNavigator> m_navigator;
+
+ OwnPtr<WorkerScriptController> m_script;
+ WorkerThread* m_thread;
+
+#if ENABLE_NOTIFICATIONS
+ mutable RefPtr<NotificationCenter> m_notifications;
+#endif
+ bool m_closing;
+ bool m_reportingException;
+ EventTargetData m_eventTargetData;
+
+ HashSet<Observer*> m_workerObservers;
+ };
+
+} // namespace WebCore
+
+#endif // ENABLE(WORKERS)
+
+#endif // WorkerContext_h
diff --git a/Source/WebCore/workers/WorkerContext.idl b/Source/WebCore/workers/WorkerContext.idl
new file mode 100644
index 0000000..45ac5b1
--- /dev/null
+++ b/Source/WebCore/workers/WorkerContext.idl
@@ -0,0 +1,127 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+module threads {
+
+ interface [
+ Conditional=WORKERS,
+ CustomMarkFunction,
+ DelegatingGetOwnPropertySlot,
+ EventTarget,
+ ExtendsDOMGlobalObject,
+ IsWorkerContext,
+ LegacyParent=JSWorkerContextBase,
+ NoStaticTables,
+ OmitConstructor
+ ] WorkerContext {
+
+ // WorkerGlobalScope
+#if defined(LANGUAGE_JAVASCRIPT) && LANGUAGE_JAVASCRIPT
+ attribute [Replaceable] WorkerContext self;
+#endif
+ attribute [Replaceable] WorkerLocation location;
+ void close();
+ attribute EventListener onerror;
+
+ // WorkerUtils
+ [Custom] void importScripts(/*[Variadic] in DOMString urls */);
+ attribute [Replaceable] WorkerNavigator navigator;
+#if defined(ENABLE_DATABASE) && ENABLE_DATABASE
+ [EnabledAtRuntime, RequiresAllArguments=Raise] Database openDatabase(in DOMString name, in DOMString version, in DOMString displayName, in unsigned long estimatedSize, in [Callback, Optional] DatabaseCallback creationCallback)
+ raises(DOMException);
+ [EnabledAtRuntime, RequiresAllArguments=Raise] DatabaseSync openDatabaseSync(in DOMString name, in DOMString version, in DOMString displayName, in unsigned long estimatedSize, in [Callback, Optional] DatabaseCallback creationCallback)
+ raises(DOMException);
+#endif
+
+ // Timers
+ [Custom] long setTimeout(in TimeoutHandler handler, in long timeout);
+ // [Custom] long setTimeout(in DOMString code, in long timeout);
+ void clearTimeout(in long handle);
+ [Custom] long setInterval(in TimeoutHandler handler, in long timeout);
+ // [Custom] long setInterval(in DOMString code, in long timeout);
+ void clearInterval(in long handle);
+
+
+ // EventTarget interface
+ void addEventListener(in DOMString type,
+ in EventListener listener,
+ in boolean useCapture);
+ void removeEventListener(in DOMString type,
+ in EventListener listener,
+ in boolean useCapture);
+ boolean dispatchEvent(in Event evt)
+ raises(EventException);
+
+#if defined(ENABLE_NOTIFICATIONS) && ENABLE_NOTIFICATIONS
+ // Notification interface
+ readonly attribute [EnabledAtRuntime] NotificationCenter webkitNotifications;
+#endif
+
+#if !defined(LANGUAGE_CPP) || !LANGUAGE_CPP
+ // Constructors
+ attribute MessageEventConstructor MessageEvent;
+ attribute WorkerLocationConstructor WorkerLocation;
+
+#if ENABLE_CHANNEL_MESSAGING
+ attribute [JSCCustomGetter] MessageChannelConstructor MessageChannel;
+#endif
+#if ENABLE_EVENTSOURCE
+ attribute [JSCCustomGetter] EventSourceConstructor EventSource;
+#endif
+ attribute [JSCCustomGetter] XMLHttpRequestConstructor XMLHttpRequest;
+#if defined(ENABLE_WEB_SOCKETS) && ENABLE_WEB_SOCKETS
+ attribute [JSCCustomGetter,EnabledAtRuntime] WebSocketConstructor WebSocket; // Usable with the new operator
+#endif
+#endif
+
+#if defined(ENABLE_BLOB) && ENABLE_BLOB
+ attribute BlobBuilderConstructor BlobBuilder;
+ attribute FileReaderConstructor FileReader;
+ attribute FileReaderSyncConstructor FileReaderSync;
+ DOMString createObjectURL(in Blob blob);
+ void revokeObjectURL(in DOMString blobURL);
+#endif
+
+#if defined(ENABLE_FILE_SYSTEM) && ENABLE_FILE_SYSTEM
+ const unsigned short TEMPORARY = 0;
+ const unsigned short PERSISTENT = 1;
+ [EnabledAtRuntime=FileSystem] void requestFileSystem(in unsigned short type, in long long size, in [Callback, Optional] FileSystemCallback successCallback, in [Callback, Optional] ErrorCallback errorCallback);
+ [EnabledAtRuntime=FileSystem] DOMFileSystemSync requestFileSystemSync(in unsigned short type, in long long size) raises (FileException);
+
+ attribute [EnabledAtRuntime=FileSystem] FlagsConstructor Flags;
+#endif
+
+ attribute [Conditional=BLOB,EnabledAtRuntime] ArrayBufferConstructor ArrayBuffer; // Usable with new operator
+ attribute [Conditional=BLOB,EnabledAtRuntime] Int8ArrayConstructor Int8Array; // Usable with new operator
+ attribute [Conditional=BLOB,EnabledAtRuntime] Uint8ArrayConstructor Uint8Array; // Usable with new operator
+ attribute [Conditional=BLOB,EnabledAtRuntime] Int16ArrayConstructor Int16Array; // Usable with new operator
+ attribute [Conditional=BLOB,EnabledAtRuntime] Uint16ArrayConstructor Uint16Array; // Usable with new operator
+ attribute [Conditional=BLOB,EnabledAtRuntime] Int32ArrayConstructor Int32Array; // Usable with new operator
+ attribute [Conditional=BLOB,EnabledAtRuntime] Uint32ArrayConstructor Uint32Array; // Usable with new operator
+ attribute [Conditional=BLOB,EnabledAtRuntime] Float32ArrayConstructor Float32Array; // Usable with new operator
+ };
+
+}
diff --git a/Source/WebCore/workers/WorkerContextProxy.h b/Source/WebCore/workers/WorkerContextProxy.h
new file mode 100644
index 0000000..4420c78
--- /dev/null
+++ b/Source/WebCore/workers/WorkerContextProxy.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef WorkerContextProxy_h
+#define WorkerContextProxy_h
+
+#if ENABLE(WORKERS)
+
+#include "MessagePort.h"
+#include <wtf/Forward.h>
+#include <wtf/PassOwnPtr.h>
+
+namespace WebCore {
+
+ class KURL;
+ class Worker;
+
+ // A proxy to talk to the worker context.
+ class WorkerContextProxy {
+ public:
+ static WorkerContextProxy* create(Worker*);
+
+ virtual ~WorkerContextProxy() {}
+
+ virtual void startWorkerContext(const KURL& scriptURL, const String& userAgent, const String& sourceCode) = 0;
+
+ virtual void terminateWorkerContext() = 0;
+
+ virtual void postMessageToWorkerContext(PassRefPtr<SerializedScriptValue>, PassOwnPtr<MessagePortChannelArray>) = 0;
+
+ virtual bool hasPendingActivity() const = 0;
+
+ virtual void workerObjectDestroyed() = 0;
+ };
+
+} // namespace WebCore
+
+#endif // ENABLE(WORKERS)
+
+#endif // WorkerContextProxy_h
diff --git a/Source/WebCore/workers/WorkerLoaderProxy.h b/Source/WebCore/workers/WorkerLoaderProxy.h
new file mode 100644
index 0000000..219dab4
--- /dev/null
+++ b/Source/WebCore/workers/WorkerLoaderProxy.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef WorkerLoaderProxy_h
+#define WorkerLoaderProxy_h
+
+#if ENABLE(WORKERS)
+
+#include "ScriptExecutionContext.h"
+#include <wtf/Forward.h>
+#include <wtf/PassOwnPtr.h>
+
+namespace WebCore {
+
+ // A proxy to talk to the loader context. Normally, the document on the main thread
+ // provides loading services for the subordinate workers. This interface provides 2-way
+ // communications to the Document context and back to the worker.
+ // Note that in multi-process browsers, the Worker object context and the Document
+ // context can be distinct.
+ class WorkerLoaderProxy {
+ public:
+ virtual ~WorkerLoaderProxy() { }
+
+ // Posts a task to the thread which runs the loading code (normally, the main thread).
+ virtual void postTaskToLoader(PassOwnPtr<ScriptExecutionContext::Task>) = 0;
+
+ // Posts callbacks from loading code to the WorkerContext. The 'mode' is used to differentiate
+ // specific synchronous loading requests so they can be 'nested', per spec.
+ virtual void postTaskForModeToWorkerContext(PassOwnPtr<ScriptExecutionContext::Task>, const String& mode) = 0;
+ };
+
+} // namespace WebCore
+
+#endif // ENABLE(WORKERS)
+
+#endif // WorkerLoaderProxy_h
diff --git a/Source/WebCore/workers/WorkerLocation.cpp b/Source/WebCore/workers/WorkerLocation.cpp
new file mode 100644
index 0000000..b934abd
--- /dev/null
+++ b/Source/WebCore/workers/WorkerLocation.cpp
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "config.h"
+
+#if ENABLE(WORKERS)
+
+#include "WorkerLocation.h"
+
+#include "PlatformString.h"
+
+namespace WebCore {
+
+String WorkerLocation::href() const
+{
+ return m_url.hasPath() ? m_url.prettyURL() : m_url.prettyURL() + "/";
+}
+
+String WorkerLocation::protocol() const
+{
+ return m_url.protocol() + ":";
+}
+
+String WorkerLocation::host() const
+{
+ return m_url.port() ? m_url.host() + ":" + String::number(m_url.port()) : m_url.host();
+}
+
+String WorkerLocation::hostname() const
+{
+ return m_url.host();
+}
+
+String WorkerLocation::port() const
+{
+ return m_url.port() ? String::number(m_url.port()) : "";
+}
+
+String WorkerLocation::pathname() const
+{
+ return m_url.path().isEmpty() ? "/" : m_url.path();
+}
+
+String WorkerLocation::search() const
+{
+ return m_url.query().isEmpty() ? "" : "?" + m_url.query();
+}
+
+String WorkerLocation::hash() const
+{
+ return m_url.fragmentIdentifier().isEmpty() ? "" : "#" + m_url.fragmentIdentifier();
+}
+
+String WorkerLocation::toString() const
+{
+ return m_url.hasPath() ? m_url.prettyURL() : m_url.prettyURL() + "/";
+}
+
+
+} // namespace WebCore
+
+#endif // ENABLE(WORKERS)
diff --git a/Source/WebCore/workers/WorkerLocation.h b/Source/WebCore/workers/WorkerLocation.h
new file mode 100644
index 0000000..5200e35
--- /dev/null
+++ b/Source/WebCore/workers/WorkerLocation.h
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef WorkerLocation_h
+#define WorkerLocation_h
+
+#if ENABLE(WORKERS)
+
+#include "KURL.h"
+#include <wtf/Forward.h>
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefCounted.h>
+#include <wtf/RefPtr.h>
+
+namespace WebCore {
+
+ class WorkerLocation : public RefCounted<WorkerLocation> {
+ public:
+ static PassRefPtr<WorkerLocation> create(const KURL& url)
+ {
+ return adoptRef(new WorkerLocation(url));
+ }
+
+ const KURL& url() const { return m_url; }
+
+ String href() const;
+
+ // URI decomposition attributes
+ String protocol() const;
+ String host() const;
+ String hostname() const;
+ String port() const;
+ String pathname() const;
+ String search() const;
+ String hash() const;
+
+ String toString() const;
+
+ private:
+ WorkerLocation(const KURL& url) : m_url(url) { }
+
+ KURL m_url;
+ };
+
+} // namespace WebCore
+
+#endif // ENABLE(WORKERS)
+
+#endif // WorkerLocation_h
diff --git a/Source/WebCore/workers/WorkerLocation.idl b/Source/WebCore/workers/WorkerLocation.idl
new file mode 100644
index 0000000..429d522
--- /dev/null
+++ b/Source/WebCore/workers/WorkerLocation.idl
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+module threads {
+
+ interface [
+ Conditional=WORKERS,
+ NoStaticTables
+ ] WorkerLocation {
+ readonly attribute DOMString href;
+ readonly attribute DOMString protocol;
+ readonly attribute DOMString host;
+ readonly attribute DOMString hostname;
+ readonly attribute DOMString port;
+ readonly attribute DOMString pathname;
+ readonly attribute DOMString search;
+ readonly attribute DOMString hash;
+
+ [DontEnum] DOMString toString();
+ };
+
+}
diff --git a/Source/WebCore/workers/WorkerMessagingProxy.cpp b/Source/WebCore/workers/WorkerMessagingProxy.cpp
new file mode 100644
index 0000000..10700c6
--- /dev/null
+++ b/Source/WebCore/workers/WorkerMessagingProxy.cpp
@@ -0,0 +1,383 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All Rights Reserved.
+ * Copyright (C) 2009 Google Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "config.h"
+
+#if ENABLE(WORKERS)
+
+#include "WorkerMessagingProxy.h"
+
+#include "CrossThreadTask.h"
+#include "DedicatedWorkerContext.h"
+#include "DedicatedWorkerThread.h"
+#include "DOMWindow.h"
+#include "Document.h"
+#include "ErrorEvent.h"
+#include "ExceptionCode.h"
+#include "InspectorController.h"
+#include "MessageEvent.h"
+#include "ScriptExecutionContext.h"
+#include "Worker.h"
+
+namespace WebCore {
+
+class MessageWorkerContextTask : public ScriptExecutionContext::Task {
+public:
+ static PassOwnPtr<MessageWorkerContextTask> create(PassRefPtr<SerializedScriptValue> message, PassOwnPtr<MessagePortChannelArray> channels)
+ {
+ return new MessageWorkerContextTask(message, channels);
+ }
+
+private:
+ MessageWorkerContextTask(PassRefPtr<SerializedScriptValue> message, PassOwnPtr<MessagePortChannelArray> channels)
+ : m_message(message)
+ , m_channels(channels)
+ {
+ }
+
+ virtual void performTask(ScriptExecutionContext* scriptContext)
+ {
+ ASSERT(scriptContext->isWorkerContext());
+ DedicatedWorkerContext* context = static_cast<DedicatedWorkerContext*>(scriptContext);
+ OwnPtr<MessagePortArray> ports = MessagePort::entanglePorts(*scriptContext, m_channels.release());
+ context->dispatchEvent(MessageEvent::create(ports.release(), m_message));
+ context->thread()->workerObjectProxy().confirmMessageFromWorkerObject(context->hasPendingActivity());
+ }
+
+private:
+ RefPtr<SerializedScriptValue> m_message;
+ OwnPtr<MessagePortChannelArray> m_channels;
+};
+
+class MessageWorkerTask : public ScriptExecutionContext::Task {
+public:
+ static PassOwnPtr<MessageWorkerTask> create(PassRefPtr<SerializedScriptValue> message, PassOwnPtr<MessagePortChannelArray> channels, WorkerMessagingProxy* messagingProxy)
+ {
+ return new MessageWorkerTask(message, channels, messagingProxy);
+ }
+
+private:
+ MessageWorkerTask(PassRefPtr<SerializedScriptValue> message, PassOwnPtr<MessagePortChannelArray> channels, WorkerMessagingProxy* messagingProxy)
+ : m_message(message)
+ , m_channels(channels)
+ , m_messagingProxy(messagingProxy)
+ {
+ }
+
+ virtual void performTask(ScriptExecutionContext* scriptContext)
+ {
+ Worker* workerObject = m_messagingProxy->workerObject();
+ if (!workerObject || m_messagingProxy->askedToTerminate())
+ return;
+
+ OwnPtr<MessagePortArray> ports = MessagePort::entanglePorts(*scriptContext, m_channels.release());
+ workerObject->dispatchEvent(MessageEvent::create(ports.release(), m_message));
+ }
+
+private:
+ RefPtr<SerializedScriptValue> m_message;
+ OwnPtr<MessagePortChannelArray> m_channels;
+ WorkerMessagingProxy* m_messagingProxy;
+};
+
+class WorkerExceptionTask : public ScriptExecutionContext::Task {
+public:
+ static PassOwnPtr<WorkerExceptionTask> create(const String& errorMessage, int lineNumber, const String& sourceURL, WorkerMessagingProxy* messagingProxy)
+ {
+ return new WorkerExceptionTask(errorMessage, lineNumber, sourceURL, messagingProxy);
+ }
+
+private:
+ WorkerExceptionTask(const String& errorMessage, int lineNumber, const String& sourceURL, WorkerMessagingProxy* messagingProxy)
+ : m_errorMessage(errorMessage.crossThreadString())
+ , m_lineNumber(lineNumber)
+ , m_sourceURL(sourceURL.crossThreadString())
+ , m_messagingProxy(messagingProxy)
+ {
+ }
+
+ virtual void performTask(ScriptExecutionContext* context)
+ {
+ Worker* workerObject = m_messagingProxy->workerObject();
+ if (!workerObject)
+ return;
+
+ // We don't bother checking the askedToTerminate() flag here, because exceptions should *always* be reported even if the thread is terminated.
+ // This is intentionally different than the behavior in MessageWorkerTask, because terminated workers no longer deliver messages (section 4.6 of the WebWorker spec), but they do report exceptions.
+
+ bool errorHandled = !workerObject->dispatchEvent(ErrorEvent::create(m_errorMessage, m_sourceURL, m_lineNumber));
+ if (!errorHandled)
+ context->reportException(m_errorMessage, m_lineNumber, m_sourceURL);
+ }
+
+ String m_errorMessage;
+ int m_lineNumber;
+ String m_sourceURL;
+ WorkerMessagingProxy* m_messagingProxy;
+};
+
+class WorkerContextDestroyedTask : public ScriptExecutionContext::Task {
+public:
+ static PassOwnPtr<WorkerContextDestroyedTask> create(WorkerMessagingProxy* messagingProxy)
+ {
+ return new WorkerContextDestroyedTask(messagingProxy);
+ }
+
+private:
+ WorkerContextDestroyedTask(WorkerMessagingProxy* messagingProxy)
+ : m_messagingProxy(messagingProxy)
+ {
+ }
+
+ virtual void performTask(ScriptExecutionContext*)
+ {
+ m_messagingProxy->workerContextDestroyedInternal();
+ }
+
+ WorkerMessagingProxy* m_messagingProxy;
+};
+
+class WorkerTerminateTask : public ScriptExecutionContext::Task {
+public:
+ static PassOwnPtr<WorkerTerminateTask> create(WorkerMessagingProxy* messagingProxy)
+ {
+ return new WorkerTerminateTask(messagingProxy);
+ }
+
+private:
+ WorkerTerminateTask(WorkerMessagingProxy* messagingProxy)
+ : m_messagingProxy(messagingProxy)
+ {
+ }
+
+ virtual void performTask(ScriptExecutionContext*)
+ {
+ m_messagingProxy->terminateWorkerContext();
+ }
+
+ WorkerMessagingProxy* m_messagingProxy;
+};
+
+class WorkerThreadActivityReportTask : public ScriptExecutionContext::Task {
+public:
+ static PassOwnPtr<WorkerThreadActivityReportTask> create(WorkerMessagingProxy* messagingProxy, bool confirmingMessage, bool hasPendingActivity)
+ {
+ return new WorkerThreadActivityReportTask(messagingProxy, confirmingMessage, hasPendingActivity);
+ }
+
+private:
+ WorkerThreadActivityReportTask(WorkerMessagingProxy* messagingProxy, bool confirmingMessage, bool hasPendingActivity)
+ : m_messagingProxy(messagingProxy)
+ , m_confirmingMessage(confirmingMessage)
+ , m_hasPendingActivity(hasPendingActivity)
+ {
+ }
+
+ virtual void performTask(ScriptExecutionContext*)
+ {
+ m_messagingProxy->reportPendingActivityInternal(m_confirmingMessage, m_hasPendingActivity);
+ }
+
+ WorkerMessagingProxy* m_messagingProxy;
+ bool m_confirmingMessage;
+ bool m_hasPendingActivity;
+};
+
+
+#if !PLATFORM(CHROMIUM)
+WorkerContextProxy* WorkerContextProxy::create(Worker* worker)
+{
+ return new WorkerMessagingProxy(worker);
+}
+#endif
+
+WorkerMessagingProxy::WorkerMessagingProxy(Worker* workerObject)
+ : m_scriptExecutionContext(workerObject->scriptExecutionContext())
+ , m_workerObject(workerObject)
+ , m_unconfirmedMessageCount(0)
+ , m_workerThreadHadPendingActivity(false)
+ , m_askedToTerminate(false)
+{
+ ASSERT(m_workerObject);
+ ASSERT((m_scriptExecutionContext->isDocument() && isMainThread())
+ || (m_scriptExecutionContext->isWorkerContext() && currentThread() == static_cast<WorkerContext*>(m_scriptExecutionContext.get())->thread()->threadID()));
+}
+
+WorkerMessagingProxy::~WorkerMessagingProxy()
+{
+ ASSERT(!m_workerObject);
+ ASSERT((m_scriptExecutionContext->isDocument() && isMainThread())
+ || (m_scriptExecutionContext->isWorkerContext() && currentThread() == static_cast<WorkerContext*>(m_scriptExecutionContext.get())->thread()->threadID()));
+}
+
+void WorkerMessagingProxy::startWorkerContext(const KURL& scriptURL, const String& userAgent, const String& sourceCode)
+{
+ RefPtr<DedicatedWorkerThread> thread = DedicatedWorkerThread::create(scriptURL, userAgent, sourceCode, *this, *this);
+ workerThreadCreated(thread);
+ thread->start();
+}
+
+void WorkerMessagingProxy::postMessageToWorkerObject(PassRefPtr<SerializedScriptValue> message, PassOwnPtr<MessagePortChannelArray> channels)
+{
+ m_scriptExecutionContext->postTask(MessageWorkerTask::create(message, channels, this));
+}
+
+void WorkerMessagingProxy::postMessageToWorkerContext(PassRefPtr<SerializedScriptValue> message, PassOwnPtr<MessagePortChannelArray> channels)
+{
+ if (m_askedToTerminate)
+ return;
+
+ if (m_workerThread) {
+ ++m_unconfirmedMessageCount;
+ m_workerThread->runLoop().postTask(MessageWorkerContextTask::create(message, channels));
+ } else
+ m_queuedEarlyTasks.append(MessageWorkerContextTask::create(message, channels));
+}
+
+void WorkerMessagingProxy::postTaskForModeToWorkerContext(PassOwnPtr<ScriptExecutionContext::Task> task, const String& mode)
+{
+ if (m_askedToTerminate)
+ return;
+
+ ASSERT(m_workerThread);
+ m_workerThread->runLoop().postTaskForMode(task, mode);
+}
+
+void WorkerMessagingProxy::postTaskToLoader(PassOwnPtr<ScriptExecutionContext::Task> task)
+{
+ // FIXME: In case of nested workers, this should go directly to the root Document context.
+ ASSERT(m_scriptExecutionContext->isDocument());
+ m_scriptExecutionContext->postTask(task);
+}
+
+void WorkerMessagingProxy::postExceptionToWorkerObject(const String& errorMessage, int lineNumber, const String& sourceURL)
+{
+ m_scriptExecutionContext->postTask(WorkerExceptionTask::create(errorMessage, lineNumber, sourceURL, this));
+}
+
+static void postConsoleMessageTask(ScriptExecutionContext* context, WorkerMessagingProxy* messagingProxy, MessageSource source, MessageType type, MessageLevel level, const String& message, unsigned lineNumber, const String& sourceURL)
+{
+ if (messagingProxy->askedToTerminate())
+ return;
+ context->addMessage(source, type, level, message, lineNumber, sourceURL);
+}
+
+void WorkerMessagingProxy::postConsoleMessageToWorkerObject(MessageSource source, MessageType type, MessageLevel level, const String& message, int lineNumber, const String& sourceURL)
+{
+ m_scriptExecutionContext->postTask(createCallbackTask(&postConsoleMessageTask, this, source, type, level, message, lineNumber, sourceURL));
+}
+
+void WorkerMessagingProxy::workerThreadCreated(PassRefPtr<DedicatedWorkerThread> workerThread)
+{
+ m_workerThread = workerThread;
+
+ if (m_askedToTerminate) {
+ // Worker.terminate() could be called from JS before the thread was created.
+ m_workerThread->stop();
+ } else {
+ unsigned taskCount = m_queuedEarlyTasks.size();
+ ASSERT(!m_unconfirmedMessageCount);
+ m_unconfirmedMessageCount = taskCount;
+ m_workerThreadHadPendingActivity = true; // Worker initialization means a pending activity.
+
+ for (unsigned i = 0; i < taskCount; ++i)
+ m_workerThread->runLoop().postTask(m_queuedEarlyTasks[i].release());
+ m_queuedEarlyTasks.clear();
+ }
+}
+
+void WorkerMessagingProxy::workerObjectDestroyed()
+{
+ m_workerObject = 0;
+ if (m_workerThread)
+ terminateWorkerContext();
+ else
+ workerContextDestroyedInternal();
+}
+
+void WorkerMessagingProxy::workerContextDestroyed()
+{
+ m_scriptExecutionContext->postTask(WorkerContextDestroyedTask::create(this));
+ // Will execute workerContextDestroyedInternal() on context's thread.
+}
+
+void WorkerMessagingProxy::workerContextClosed()
+{
+ // Executes terminateWorkerContext() on parent context's thread.
+ m_scriptExecutionContext->postTask(WorkerTerminateTask::create(this));
+}
+
+void WorkerMessagingProxy::workerContextDestroyedInternal()
+{
+ // WorkerContextDestroyedTask is always the last to be performed, so the proxy is not needed for communication
+ // in either side any more. However, the Worker object may still exist, and it assumes that the proxy exists, too.
+ m_askedToTerminate = true;
+ m_workerThread = 0;
+ if (!m_workerObject)
+ delete this;
+}
+
+void WorkerMessagingProxy::terminateWorkerContext()
+{
+ if (m_askedToTerminate)
+ return;
+ m_askedToTerminate = true;
+
+ if (m_workerThread)
+ m_workerThread->stop();
+}
+
+void WorkerMessagingProxy::confirmMessageFromWorkerObject(bool hasPendingActivity)
+{
+ m_scriptExecutionContext->postTask(WorkerThreadActivityReportTask::create(this, true, hasPendingActivity));
+ // Will execute reportPendingActivityInternal() on context's thread.
+}
+
+void WorkerMessagingProxy::reportPendingActivity(bool hasPendingActivity)
+{
+ m_scriptExecutionContext->postTask(WorkerThreadActivityReportTask::create(this, false, hasPendingActivity));
+ // Will execute reportPendingActivityInternal() on context's thread.
+}
+
+void WorkerMessagingProxy::reportPendingActivityInternal(bool confirmingMessage, bool hasPendingActivity)
+{
+ if (confirmingMessage && !m_askedToTerminate) {
+ ASSERT(m_unconfirmedMessageCount);
+ --m_unconfirmedMessageCount;
+ }
+
+ m_workerThreadHadPendingActivity = hasPendingActivity;
+}
+
+bool WorkerMessagingProxy::hasPendingActivity() const
+{
+ return (m_unconfirmedMessageCount || m_workerThreadHadPendingActivity) && !m_askedToTerminate;
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(WORKERS)
diff --git a/Source/WebCore/workers/WorkerMessagingProxy.h b/Source/WebCore/workers/WorkerMessagingProxy.h
new file mode 100644
index 0000000..33937ce
--- /dev/null
+++ b/Source/WebCore/workers/WorkerMessagingProxy.h
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef WorkerMessagingProxy_h
+#define WorkerMessagingProxy_h
+
+#if ENABLE(WORKERS)
+
+#include "ScriptExecutionContext.h"
+#include "WorkerContextProxy.h"
+#include "WorkerLoaderProxy.h"
+#include "WorkerObjectProxy.h"
+#include <wtf/Forward.h>
+#include <wtf/Noncopyable.h>
+#include <wtf/PassOwnPtr.h>
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefPtr.h>
+#include <wtf/Vector.h>
+
+namespace WebCore {
+
+ class DedicatedWorkerThread;
+ class ScriptExecutionContext;
+ class Worker;
+
+ class WorkerMessagingProxy : public WorkerContextProxy, public WorkerObjectProxy, public WorkerLoaderProxy, public Noncopyable {
+ public:
+ WorkerMessagingProxy(Worker*);
+
+ // Implementations of WorkerContextProxy.
+ // (Only use these methods in the worker object thread.)
+ virtual void startWorkerContext(const KURL& scriptURL, const String& userAgent, const String& sourceCode);
+ virtual void terminateWorkerContext();
+ virtual void postMessageToWorkerContext(PassRefPtr<SerializedScriptValue>, PassOwnPtr<MessagePortChannelArray>);
+ virtual bool hasPendingActivity() const;
+ virtual void workerObjectDestroyed();
+
+ // Implementations of WorkerObjectProxy.
+ // (Only use these methods in the worker context thread.)
+ virtual void postMessageToWorkerObject(PassRefPtr<SerializedScriptValue>, PassOwnPtr<MessagePortChannelArray>);
+ virtual void postExceptionToWorkerObject(const String& errorMessage, int lineNumber, const String& sourceURL);
+ virtual void postConsoleMessageToWorkerObject(MessageSource, MessageType, MessageLevel, const String& message, int lineNumber, const String& sourceURL);
+ virtual void confirmMessageFromWorkerObject(bool hasPendingActivity);
+ virtual void reportPendingActivity(bool hasPendingActivity);
+ virtual void workerContextClosed();
+ virtual void workerContextDestroyed();
+
+ // Implementation of WorkerLoaderProxy.
+ // These methods are called on different threads to schedule loading
+ // requests and to send callbacks back to WorkerContext.
+ virtual void postTaskToLoader(PassOwnPtr<ScriptExecutionContext::Task>);
+ virtual void postTaskForModeToWorkerContext(PassOwnPtr<ScriptExecutionContext::Task>, const String& mode);
+
+ void workerThreadCreated(PassRefPtr<DedicatedWorkerThread>);
+
+ // Only use this method on the worker object thread.
+ bool askedToTerminate() const { return m_askedToTerminate; }
+
+ private:
+ friend class MessageWorkerTask;
+ friend class WorkerContextDestroyedTask;
+ friend class WorkerExceptionTask;
+ friend class WorkerThreadActivityReportTask;
+
+ virtual ~WorkerMessagingProxy();
+
+ void workerContextDestroyedInternal();
+ void reportPendingActivityInternal(bool confirmingMessage, bool hasPendingActivity);
+ Worker* workerObject() const { return m_workerObject; }
+
+ RefPtr<ScriptExecutionContext> m_scriptExecutionContext;
+ Worker* m_workerObject;
+ RefPtr<DedicatedWorkerThread> m_workerThread;
+
+ unsigned m_unconfirmedMessageCount; // Unconfirmed messages from worker object to worker thread.
+ bool m_workerThreadHadPendingActivity; // The latest confirmation from worker thread reported that it was still active.
+
+ bool m_askedToTerminate;
+
+ Vector<OwnPtr<ScriptExecutionContext::Task> > m_queuedEarlyTasks; // Tasks are queued here until there's a thread object created.
+ };
+
+} // namespace WebCore
+
+#endif // ENABLE(WORKERS)
+
+#endif // WorkerMessagingProxy_h
diff --git a/Source/WebCore/workers/WorkerObjectProxy.h b/Source/WebCore/workers/WorkerObjectProxy.h
new file mode 100644
index 0000000..33e0bc3
--- /dev/null
+++ b/Source/WebCore/workers/WorkerObjectProxy.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef WorkerObjectProxy_h
+#define WorkerObjectProxy_h
+
+#if ENABLE(WORKERS)
+
+#include "WorkerReportingProxy.h"
+#include "MessagePort.h"
+#include <wtf/PassOwnPtr.h>
+
+namespace WebCore {
+
+ class MessagePortChannel;
+
+ // A proxy to talk to the worker object.
+ class WorkerObjectProxy : public WorkerReportingProxy {
+ public:
+ virtual void postMessageToWorkerObject(PassRefPtr<SerializedScriptValue>, PassOwnPtr<MessagePortChannelArray>) = 0;
+
+ virtual void confirmMessageFromWorkerObject(bool hasPendingActivity) = 0;
+ virtual void reportPendingActivity(bool hasPendingActivity) = 0;
+
+ // No need to notify the parent page context when dedicated workers are closing.
+ virtual void workerContextClosed() { }
+ };
+
+} // namespace WebCore
+
+#endif // ENABLE(WORKERS)
+
+#endif // WorkerObjectProxy_h
diff --git a/Source/WebCore/workers/WorkerReportingProxy.h b/Source/WebCore/workers/WorkerReportingProxy.h
new file mode 100644
index 0000000..6a8fcef
--- /dev/null
+++ b/Source/WebCore/workers/WorkerReportingProxy.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef WorkerReportingProxy_h
+#define WorkerReportingProxy_h
+
+#if ENABLE(WORKERS)
+
+#include <wtf/Forward.h>
+
+#include "Console.h"
+
+namespace WebCore {
+
+ // APIs used by workers to report console activity.
+ class WorkerReportingProxy {
+ public:
+ virtual ~WorkerReportingProxy() {}
+
+ virtual void postExceptionToWorkerObject(const String& errorMessage, int lineNumber, const String& sourceURL) = 0;
+
+ virtual void postConsoleMessageToWorkerObject(MessageSource, MessageType, MessageLevel, const String& message, int lineNumber, const String& sourceURL) = 0;
+
+ // Invoked when close() is invoked on the worker context.
+ virtual void workerContextClosed() = 0;
+
+ // Invoked when the thread has stopped.
+ virtual void workerContextDestroyed() = 0;
+ };
+} // namespace WebCore
+
+#endif // ENABLE(WORKERS)
+
+#endif // WorkerReportingProxy_h
diff --git a/Source/WebCore/workers/WorkerRunLoop.cpp b/Source/WebCore/workers/WorkerRunLoop.cpp
new file mode 100644
index 0000000..83f243f
--- /dev/null
+++ b/Source/WebCore/workers/WorkerRunLoop.cpp
@@ -0,0 +1,210 @@
+/*
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#if ENABLE(WORKERS)
+
+#include "ScriptExecutionContext.h"
+#include "SharedTimer.h"
+#include "ThreadGlobalData.h"
+#include "ThreadTimers.h"
+#include "WorkerRunLoop.h"
+#include "WorkerContext.h"
+#include "WorkerThread.h"
+
+namespace WebCore {
+
+class WorkerSharedTimer : public SharedTimer {
+public:
+ WorkerSharedTimer()
+ : m_sharedTimerFunction(0)
+ , m_nextFireTime(0)
+ {
+ }
+
+ // SharedTimer interface.
+ virtual void setFiredFunction(void (*function)()) { m_sharedTimerFunction = function; }
+ virtual void setFireTime(double fireTime) { m_nextFireTime = fireTime; }
+ virtual void stop() { m_nextFireTime = 0; }
+
+ bool isActive() { return m_sharedTimerFunction && m_nextFireTime; }
+ double fireTime() { return m_nextFireTime; }
+ void fire() { m_sharedTimerFunction(); }
+
+private:
+ void (*m_sharedTimerFunction)();
+ double m_nextFireTime;
+};
+
+class ModePredicate {
+public:
+ ModePredicate(const String& mode)
+ : m_mode(mode)
+ , m_defaultMode(mode == WorkerRunLoop::defaultMode())
+ {
+ }
+
+ bool isDefaultMode() const
+ {
+ return m_defaultMode;
+ }
+
+ bool operator()(WorkerRunLoop::Task* task) const
+ {
+ return m_defaultMode || m_mode == task->mode();
+ }
+
+private:
+ String m_mode;
+ bool m_defaultMode;
+};
+
+WorkerRunLoop::WorkerRunLoop()
+ : m_sharedTimer(new WorkerSharedTimer)
+ , m_nestedCount(0)
+ , m_uniqueId(0)
+{
+}
+
+WorkerRunLoop::~WorkerRunLoop()
+{
+ ASSERT(!m_nestedCount);
+}
+
+String WorkerRunLoop::defaultMode()
+{
+ return String();
+}
+
+class RunLoopSetup : public Noncopyable {
+public:
+ RunLoopSetup(WorkerRunLoop& runLoop)
+ : m_runLoop(runLoop)
+ {
+ if (!m_runLoop.m_nestedCount)
+ threadGlobalData().threadTimers().setSharedTimer(m_runLoop.m_sharedTimer.get());
+ m_runLoop.m_nestedCount++;
+ }
+
+ ~RunLoopSetup()
+ {
+ m_runLoop.m_nestedCount--;
+ if (!m_runLoop.m_nestedCount)
+ threadGlobalData().threadTimers().setSharedTimer(0);
+ }
+private:
+ WorkerRunLoop& m_runLoop;
+};
+
+void WorkerRunLoop::run(WorkerContext* context)
+{
+ RunLoopSetup setup(*this);
+ ModePredicate modePredicate(defaultMode());
+ MessageQueueWaitResult result;
+ do {
+ result = runInMode(context, modePredicate);
+ } while (result != MessageQueueTerminated);
+}
+
+MessageQueueWaitResult WorkerRunLoop::runInMode(WorkerContext* context, const String& mode)
+{
+ RunLoopSetup setup(*this);
+ ModePredicate modePredicate(mode);
+ MessageQueueWaitResult result = runInMode(context, modePredicate);
+ return result;
+}
+
+MessageQueueWaitResult WorkerRunLoop::runInMode(WorkerContext* context, const ModePredicate& predicate)
+{
+ ASSERT(context);
+ ASSERT(context->thread());
+ ASSERT(context->thread()->threadID() == currentThread());
+
+ double absoluteTime = (predicate.isDefaultMode() && m_sharedTimer->isActive()) ? m_sharedTimer->fireTime() : MessageQueue<Task>::infiniteTime();
+ MessageQueueWaitResult result;
+ OwnPtr<WorkerRunLoop::Task> task = m_messageQueue.waitForMessageFilteredWithTimeout(result, predicate, absoluteTime);
+
+ // If the context is closing, don't execute any further JavaScript tasks (per section 4.1.1 of the Web Workers spec). However, there may be implementation cleanup tasks in the queue, so keep running through it.
+
+ switch (result) {
+ case MessageQueueTerminated:
+ break;
+
+ case MessageQueueMessageReceived:
+ task->performTask(context);
+ break;
+
+ case MessageQueueTimeout:
+ if (!context->isClosing())
+ m_sharedTimer->fire();
+ break;
+ }
+
+ return result;
+}
+
+void WorkerRunLoop::terminate()
+{
+ m_messageQueue.kill();
+}
+
+void WorkerRunLoop::postTask(PassOwnPtr<ScriptExecutionContext::Task> task)
+{
+ postTaskForMode(task, defaultMode());
+}
+
+void WorkerRunLoop::postTaskForMode(PassOwnPtr<ScriptExecutionContext::Task> task, const String& mode)
+{
+ m_messageQueue.append(Task::create(task, mode.crossThreadString()));
+}
+
+PassOwnPtr<WorkerRunLoop::Task> WorkerRunLoop::Task::create(PassOwnPtr<ScriptExecutionContext::Task> task, const String& mode)
+{
+ return new Task(task, mode);
+}
+
+void WorkerRunLoop::Task::performTask(ScriptExecutionContext* context)
+{
+ WorkerContext* workerContext = static_cast<WorkerContext *>(context);
+ if (!workerContext->isClosing() || m_task->isCleanupTask())
+ m_task->performTask(context);
+}
+
+WorkerRunLoop::Task::Task(PassOwnPtr<ScriptExecutionContext::Task> task, const String& mode)
+ : m_task(task)
+ , m_mode(mode.crossThreadString())
+{
+}
+
+
+} // namespace WebCore
+
+#endif // ENABLE(WORKERS)
diff --git a/Source/WebCore/workers/WorkerRunLoop.h b/Source/WebCore/workers/WorkerRunLoop.h
new file mode 100644
index 0000000..9d4edfd
--- /dev/null
+++ b/Source/WebCore/workers/WorkerRunLoop.h
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef WorkerRunLoop_h
+#define WorkerRunLoop_h
+
+#if ENABLE(WORKERS)
+
+#include "ScriptExecutionContext.h"
+#include <wtf/MessageQueue.h>
+#include <wtf/OwnPtr.h>
+#include <wtf/PassOwnPtr.h>
+
+namespace WebCore {
+
+ class ModePredicate;
+ class WorkerContext;
+ class WorkerSharedTimer;
+
+ class WorkerRunLoop {
+ public:
+ WorkerRunLoop();
+ ~WorkerRunLoop();
+
+ // Blocking call. Waits for tasks and timers, invokes the callbacks.
+ void run(WorkerContext*);
+
+ // Waits for a single task and returns.
+ MessageQueueWaitResult runInMode(WorkerContext*, const String& mode);
+
+ void terminate();
+ bool terminated() { return m_messageQueue.killed(); }
+
+ void postTask(PassOwnPtr<ScriptExecutionContext::Task>);
+ void postTaskForMode(PassOwnPtr<ScriptExecutionContext::Task>, const String& mode);
+
+ unsigned long createUniqueId() { return ++m_uniqueId; }
+
+ static String defaultMode();
+
+ class Task : public Noncopyable {
+ public:
+ static PassOwnPtr<Task> create(PassOwnPtr<ScriptExecutionContext::Task> task, const String& mode);
+ ~Task() { }
+ const String& mode() const { return m_mode; }
+ void performTask(ScriptExecutionContext* context);
+
+ private:
+ Task(PassOwnPtr<ScriptExecutionContext::Task> task, const String& mode);
+
+ OwnPtr<ScriptExecutionContext::Task> m_task;
+ String m_mode;
+ };
+
+ private:
+ friend class RunLoopSetup;
+ MessageQueueWaitResult runInMode(WorkerContext*, const ModePredicate&);
+
+ MessageQueue<Task> m_messageQueue;
+ OwnPtr<WorkerSharedTimer> m_sharedTimer;
+ int m_nestedCount;
+ unsigned long m_uniqueId;
+ };
+
+} // namespace WebCore
+
+#endif // ENABLE(WORKERS)
+
+#endif // WorkerRunLoop_h
diff --git a/Source/WebCore/workers/WorkerScriptLoader.cpp b/Source/WebCore/workers/WorkerScriptLoader.cpp
new file mode 100644
index 0000000..1786b89
--- /dev/null
+++ b/Source/WebCore/workers/WorkerScriptLoader.cpp
@@ -0,0 +1,171 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All Rights Reserved.
+ * Copyright (C) 2009 Google Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "config.h"
+
+#if ENABLE(WORKERS)
+
+#include "WorkerScriptLoader.h"
+
+#include "CrossThreadTask.h"
+#include "ResourceRequest.h"
+#include "ScriptExecutionContext.h"
+#include "SecurityOrigin.h"
+#include "WorkerContext.h"
+#include "WorkerScriptLoaderClient.h"
+#include "WorkerThreadableLoader.h"
+#include <wtf/OwnPtr.h>
+#include <wtf/UnusedParam.h>
+
+namespace WebCore {
+
+WorkerScriptLoader::WorkerScriptLoader(ResourceRequestBase::TargetType targetType)
+ : m_client(0)
+ , m_failed(false)
+ , m_identifier(0)
+ , m_targetType(targetType)
+{
+}
+
+void WorkerScriptLoader::loadSynchronously(ScriptExecutionContext* scriptExecutionContext, const KURL& url, CrossOriginRequestPolicy crossOriginRequestPolicy)
+{
+ m_url = url;
+
+ OwnPtr<ResourceRequest> request(createResourceRequest());
+ if (!request)
+ return;
+
+ ASSERT(scriptExecutionContext->isWorkerContext());
+
+ ThreadableLoaderOptions options;
+ options.allowCredentials = true;
+ options.crossOriginRequestPolicy = crossOriginRequestPolicy;
+ options.sendLoadCallbacks = true;
+
+ WorkerThreadableLoader::loadResourceSynchronously(static_cast<WorkerContext*>(scriptExecutionContext), *request, *this, options);
+}
+
+void WorkerScriptLoader::loadAsynchronously(ScriptExecutionContext* scriptExecutionContext, const KURL& url, CrossOriginRequestPolicy crossOriginRequestPolicy, WorkerScriptLoaderClient* client)
+{
+ ASSERT(client);
+ m_client = client;
+ m_url = url;
+
+ OwnPtr<ResourceRequest> request(createResourceRequest());
+ if (!request)
+ return;
+
+ ThreadableLoaderOptions options;
+ options.allowCredentials = true;
+ options.crossOriginRequestPolicy = crossOriginRequestPolicy;
+ options.sendLoadCallbacks = true;
+
+ m_threadableLoader = ThreadableLoader::create(scriptExecutionContext, this, *request, options);
+}
+
+PassOwnPtr<ResourceRequest> WorkerScriptLoader::createResourceRequest()
+{
+ OwnPtr<ResourceRequest> request(new ResourceRequest(m_url));
+ request->setHTTPMethod("GET");
+ request->setTargetType(m_targetType);
+ return request.release();
+}
+
+void WorkerScriptLoader::didReceiveResponse(const ResourceResponse& response)
+{
+ if (response.httpStatusCode() / 100 != 2 && response.httpStatusCode()) {
+ m_failed = true;
+ return;
+ }
+ m_responseEncoding = response.textEncodingName();
+ if (m_client)
+ m_client->didReceiveResponse(response);
+}
+
+void WorkerScriptLoader::didReceiveData(const char* data, int len)
+{
+ if (m_failed)
+ return;
+
+ if (!m_decoder) {
+ if (!m_responseEncoding.isEmpty())
+ m_decoder = TextResourceDecoder::create("text/javascript", m_responseEncoding);
+ else
+ m_decoder = TextResourceDecoder::create("text/javascript", "UTF-8");
+ }
+
+ if (!len)
+ return;
+
+ if (len == -1)
+ len = strlen(data);
+
+ m_script += m_decoder->decode(data, len);
+}
+
+void WorkerScriptLoader::didFinishLoading(unsigned long identifier)
+{
+ if (m_failed)
+ return;
+
+ if (m_decoder)
+ m_script += m_decoder->flush();
+
+ m_identifier = identifier;
+ notifyFinished();
+}
+
+void WorkerScriptLoader::didFail(const ResourceError&)
+{
+ notifyError();
+}
+
+void WorkerScriptLoader::didFailRedirectCheck()
+{
+ notifyError();
+}
+
+void WorkerScriptLoader::didReceiveAuthenticationCancellation(const ResourceResponse&)
+{
+ notifyError();
+}
+
+void WorkerScriptLoader::notifyError()
+{
+ m_failed = true;
+ notifyFinished();
+}
+
+void WorkerScriptLoader::notifyFinished()
+{
+ if (m_client)
+ m_client->notifyFinished();
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(WORKERS)
diff --git a/Source/WebCore/workers/WorkerScriptLoader.h b/Source/WebCore/workers/WorkerScriptLoader.h
new file mode 100644
index 0000000..fc8b0b4
--- /dev/null
+++ b/Source/WebCore/workers/WorkerScriptLoader.h
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All Rights Reserved.
+ * Copyright (C) 2009 Google Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef WorkerScriptLoader_h
+#define WorkerScriptLoader_h
+
+#if ENABLE(WORKERS)
+
+#include "KURL.h"
+#include "ResourceRequest.h"
+#include "ResourceResponse.h"
+#include "TextResourceDecoder.h"
+#include "ThreadableLoader.h"
+#include "ThreadableLoaderClient.h"
+
+namespace WebCore {
+
+ class ScriptExecutionContext;
+ class WorkerScriptLoaderClient;
+
+ class WorkerScriptLoader : public ThreadableLoaderClient {
+ public:
+ explicit WorkerScriptLoader(ResourceRequestBase::TargetType);
+
+ void loadSynchronously(ScriptExecutionContext*, const KURL&, CrossOriginRequestPolicy);
+ void loadAsynchronously(ScriptExecutionContext*, const KURL&, CrossOriginRequestPolicy, WorkerScriptLoaderClient*);
+
+ void notifyError();
+
+ const String& script() const { return m_script; }
+ const KURL& url() const { return m_url; }
+ bool failed() const { return m_failed; }
+ unsigned long identifier() const { return m_identifier; }
+
+ virtual void didReceiveResponse(const ResourceResponse&);
+ virtual void didReceiveData(const char* data, int lengthReceived);
+ virtual void didFinishLoading(unsigned long identifier);
+ virtual void didFail(const ResourceError&);
+ virtual void didFailRedirectCheck();
+ virtual void didReceiveAuthenticationCancellation(const ResourceResponse&);
+
+ private:
+ PassOwnPtr<ResourceRequest> createResourceRequest();
+ void notifyFinished();
+
+ WorkerScriptLoaderClient* m_client;
+ RefPtr<ThreadableLoader> m_threadableLoader;
+ String m_responseEncoding;
+ RefPtr<TextResourceDecoder> m_decoder;
+ String m_script;
+ KURL m_url;
+ bool m_failed;
+ unsigned long m_identifier;
+ ResourceRequestBase::TargetType m_targetType;
+ };
+
+} // namespace WebCore
+
+#endif // ENABLE(WORKERS)
+
+#endif // WorkerScriptLoader_h
diff --git a/Source/WebCore/workers/WorkerScriptLoaderClient.h b/Source/WebCore/workers/WorkerScriptLoaderClient.h
new file mode 100644
index 0000000..2f4569e
--- /dev/null
+++ b/Source/WebCore/workers/WorkerScriptLoaderClient.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All Rights Reserved.
+ * Copyright (C) 2009 Google Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef WorkerScriptLoaderClient_h
+#define WorkerScriptLoaderClient_h
+
+#if ENABLE(WORKERS)
+
+namespace WebCore {
+
+ class ResourceResponse;
+
+ class WorkerScriptLoaderClient {
+ public:
+ virtual void didReceiveResponse(const ResourceResponse&) { }
+
+ // FIXME: notifyFinished() is not currently guaranteed to be invoked if used from worker context and the worker shuts down in the middle of an operation.
+ // This will cause leaks when we support nested workers.
+ virtual void notifyFinished() { }
+
+ protected:
+ virtual ~WorkerScriptLoaderClient() { }
+ };
+
+} // namespace WebCore
+
+#endif // ENABLE(WORKERS)
+
+#endif // WorkerScriptLoaderClient_h
diff --git a/Source/WebCore/workers/WorkerThread.cpp b/Source/WebCore/workers/WorkerThread.cpp
new file mode 100644
index 0000000..f61120e
--- /dev/null
+++ b/Source/WebCore/workers/WorkerThread.cpp
@@ -0,0 +1,248 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "config.h"
+
+#if ENABLE(WORKERS)
+
+#include "WorkerThread.h"
+
+#include "DedicatedWorkerContext.h"
+#include "KURL.h"
+#include "PlatformString.h"
+#include "ScriptSourceCode.h"
+#include "ScriptValue.h"
+#include "ThreadGlobalData.h"
+
+#include <utility>
+#include <wtf/Noncopyable.h>
+
+#if ENABLE(DATABASE)
+#include "DatabaseTask.h"
+#include "DatabaseTracker.h"
+#endif
+
+namespace WebCore {
+
+static Mutex& threadCountMutex()
+{
+ AtomicallyInitializedStatic(Mutex&, mutex = *new Mutex);
+ return mutex;
+}
+
+unsigned WorkerThread::m_threadCount = 0;
+
+unsigned WorkerThread::workerThreadCount()
+{
+ MutexLocker lock(threadCountMutex());
+ return m_threadCount;
+}
+
+struct WorkerThreadStartupData : Noncopyable {
+public:
+ static PassOwnPtr<WorkerThreadStartupData> create(const KURL& scriptURL, const String& userAgent, const String& sourceCode)
+ {
+ return new WorkerThreadStartupData(scriptURL, userAgent, sourceCode);
+ }
+
+ KURL m_scriptURL;
+ String m_userAgent;
+ String m_sourceCode;
+private:
+ WorkerThreadStartupData(const KURL& scriptURL, const String& userAgent, const String& sourceCode);
+};
+
+WorkerThreadStartupData::WorkerThreadStartupData(const KURL& scriptURL, const String& userAgent, const String& sourceCode)
+ : m_scriptURL(scriptURL.copy())
+ , m_userAgent(userAgent.crossThreadString())
+ , m_sourceCode(sourceCode.crossThreadString())
+{
+}
+
+WorkerThread::WorkerThread(const KURL& scriptURL, const String& userAgent, const String& sourceCode, WorkerLoaderProxy& workerLoaderProxy, WorkerReportingProxy& workerReportingProxy)
+ : m_threadID(0)
+ , m_workerLoaderProxy(workerLoaderProxy)
+ , m_workerReportingProxy(workerReportingProxy)
+ , m_startupData(WorkerThreadStartupData::create(scriptURL, userAgent, sourceCode))
+{
+ MutexLocker lock(threadCountMutex());
+ m_threadCount++;
+}
+
+WorkerThread::~WorkerThread()
+{
+ MutexLocker lock(threadCountMutex());
+ ASSERT(m_threadCount > 0);
+ m_threadCount--;
+}
+
+bool WorkerThread::start()
+{
+ // Mutex protection is necessary to ensure that m_threadID is initialized when the thread starts.
+ MutexLocker lock(m_threadCreationMutex);
+
+ if (m_threadID)
+ return true;
+
+ m_threadID = createThread(WorkerThread::workerThreadStart, this, "WebCore: Worker");
+
+ return m_threadID;
+}
+
+void* WorkerThread::workerThreadStart(void* thread)
+{
+ return static_cast<WorkerThread*>(thread)->workerThread();
+}
+
+void* WorkerThread::workerThread()
+{
+ {
+ MutexLocker lock(m_threadCreationMutex);
+ m_workerContext = createWorkerContext(m_startupData->m_scriptURL, m_startupData->m_userAgent);
+
+ if (m_runLoop.terminated()) {
+ // The worker was terminated before the thread had a chance to run. Since the context didn't exist yet,
+ // forbidExecution() couldn't be called from stop().
+ m_workerContext->script()->forbidExecution(WorkerScriptController::TerminateRunningScript);
+ }
+ }
+
+ WorkerScriptController* script = m_workerContext->script();
+ script->evaluate(ScriptSourceCode(m_startupData->m_sourceCode, m_startupData->m_scriptURL));
+ // Free the startup data to cause its member variable deref's happen on the worker's thread (since
+ // all ref/derefs of these objects are happening on the thread at this point). Note that
+ // WorkerThread::~WorkerThread happens on a different thread where it was created.
+ m_startupData.clear();
+
+ runEventLoop();
+
+ ThreadIdentifier threadID = m_threadID;
+
+ ASSERT(m_workerContext->hasOneRef());
+
+ // The below assignment will destroy the context, which will in turn notify messaging proxy.
+ // We cannot let any objects survive past thread exit, because no other thread will run GC or otherwise destroy them.
+ m_workerContext = 0;
+
+ // Clean up WebCore::ThreadGlobalData before WTF::WTFThreadData goes away!
+ threadGlobalData().destroy();
+
+ // The thread object may be already destroyed from notification now, don't try to access "this".
+ detachThread(threadID);
+
+ return 0;
+}
+
+void WorkerThread::runEventLoop()
+{
+ // Does not return until terminated.
+ m_runLoop.run(m_workerContext.get());
+}
+
+class WorkerThreadShutdownFinishTask : public ScriptExecutionContext::Task {
+public:
+ static PassOwnPtr<WorkerThreadShutdownFinishTask> create()
+ {
+ return new WorkerThreadShutdownFinishTask();
+ }
+
+ virtual void performTask(ScriptExecutionContext *context)
+ {
+ ASSERT(context->isWorkerContext());
+ WorkerContext* workerContext = static_cast<WorkerContext*>(context);
+ // It's not safe to call clearScript until all the cleanup tasks posted by functions initiated by WorkerThreadShutdownStartTask have completed.
+ workerContext->clearScript();
+ workerContext->thread()->runLoop().terminate();
+ }
+
+ virtual bool isCleanupTask() const { return true; }
+};
+
+class WorkerThreadShutdownStartTask : public ScriptExecutionContext::Task {
+public:
+ static PassOwnPtr<WorkerThreadShutdownStartTask> create()
+ {
+ return new WorkerThreadShutdownStartTask();
+ }
+
+ virtual void performTask(ScriptExecutionContext *context)
+ {
+ ASSERT(context->isWorkerContext());
+ WorkerContext* workerContext = static_cast<WorkerContext*>(context);
+
+#if ENABLE(DATABASE)
+ // We currently ignore any DatabasePolicy used for the document's
+ // databases; if it's actually used anywhere, this should be revisited.
+ DatabaseTaskSynchronizer cleanupSync;
+ workerContext->stopDatabases(&cleanupSync);
+#endif
+
+ workerContext->stopActiveDOMObjects();
+
+ workerContext->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.
+ workerContext->removeAllEventListeners();
+
+#if ENABLE(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.
+ workerContext->postTask(WorkerThreadShutdownFinishTask::create());
+ }
+
+ virtual bool isCleanupTask() const { return true; }
+};
+
+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_workerContext) {
+ m_workerContext->script()->forbidExecution(WorkerScriptController::TerminateRunningScript);
+
+#if ENABLE(DATABASE)
+ DatabaseTracker::tracker().interruptAllDatabasesForContext(m_workerContext.get());
+#endif
+
+ // FIXME: Rudely killing the thread won't work when we allow nested workers, because they will try to post notifications of their destruction.
+ // This can likely use the same mechanism as used for databases above.
+
+ m_runLoop.postTask(WorkerThreadShutdownStartTask::create());
+ } else
+ m_runLoop.terminate();
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(WORKERS)
diff --git a/Source/WebCore/workers/WorkerThread.h b/Source/WebCore/workers/WorkerThread.h
new file mode 100644
index 0000000..e44afce
--- /dev/null
+++ b/Source/WebCore/workers/WorkerThread.h
@@ -0,0 +1,106 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef WorkerThread_h
+#define WorkerThread_h
+
+#if ENABLE(WORKERS)
+
+#include "WorkerRunLoop.h"
+#include <wtf/Forward.h>
+#include <wtf/OwnPtr.h>
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefCounted.h>
+
+namespace WebCore {
+
+ class KURL;
+ class NotificationPresenter;
+ class WorkerContext;
+ class WorkerLoaderProxy;
+ class WorkerReportingProxy;
+ struct WorkerThreadStartupData;
+
+ class WorkerThread : public RefCounted<WorkerThread> {
+ public:
+ virtual ~WorkerThread();
+
+ bool start();
+ void stop();
+
+ ThreadIdentifier threadID() const { return m_threadID; }
+ WorkerRunLoop& runLoop() { return m_runLoop; }
+ WorkerLoaderProxy& workerLoaderProxy() const { return m_workerLoaderProxy; }
+ WorkerReportingProxy& workerReportingProxy() const { return m_workerReportingProxy; }
+
+ // Number of active worker threads.
+ static unsigned workerThreadCount();
+
+#if ENABLE(NOTIFICATIONS)
+ NotificationPresenter* getNotificationPresenter() { return m_notificationPresenter; }
+ void setNotificationPresenter(NotificationPresenter* presenter) { m_notificationPresenter = presenter; }
+#endif
+
+ protected:
+ WorkerThread(const KURL&, const String& userAgent, const String& sourceCode, WorkerLoaderProxy&, WorkerReportingProxy&);
+
+ // Factory method for creating a new worker context for the thread.
+ virtual PassRefPtr<WorkerContext> createWorkerContext(const KURL& url, const String& userAgent) = 0;
+
+ // Executes the event loop for the worker thread. Derived classes can override to perform actions before/after entering the event loop.
+ virtual void runEventLoop();
+
+ WorkerContext* workerContext() { return m_workerContext.get(); }
+
+ private:
+ // Static function executed as the core routine on the new thread. Passed a pointer to a WorkerThread object.
+ static void* workerThreadStart(void*);
+ void* workerThread();
+
+ ThreadIdentifier m_threadID;
+ WorkerRunLoop m_runLoop;
+ WorkerLoaderProxy& m_workerLoaderProxy;
+ WorkerReportingProxy& m_workerReportingProxy;
+
+ RefPtr<WorkerContext> m_workerContext;
+ Mutex m_threadCreationMutex;
+
+ OwnPtr<WorkerThreadStartupData> m_startupData;
+
+#if ENABLE(NOTIFICATIONS)
+ NotificationPresenter* m_notificationPresenter;
+#endif
+
+ // Track the number of WorkerThread instances for use in layout tests.
+ static unsigned m_threadCount;
+ };
+
+} // namespace WebCore
+
+#endif // ENABLE(WORKERS)
+
+#endif // WorkerThread_h
+