[SCM] WebKit Debian packaging branch, webkit-1.1, updated. upstream/1.1.16-1409-g5afdf4d
eric at webkit.org
eric at webkit.org
Thu Dec 3 13:31:12 UTC 2009
The following commit has been merged in the webkit-1.1 branch:
commit 854c71267850cfd892309c54d856fc66df0d3176
Author: eric at webkit.org <eric at webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date: Tue Nov 10 19:52:46 2009 +0000
2009-11-10 Yaar Schnitman <yaar at chromium.org>
Reviewed by Dimitri Glazkov.
Up-streaming Chromium API src files: WebWorker and friends.
https://bugs.webkit.org/show_bug.cgi?id=31276
* src/WebWorkerBase.cpp: Added.
(WebKit::WorkerWebFrameClient::didCreateDataSource):
(WebKit::WorkerWebFrameClient::sharedInstance):
(WebKit::WorkerWebFrameClient::WorkerWebFrameClient):
(WebKit::initializeWebKitStaticValues):
(WebKit::WebWorkerBase::WebWorkerBase):
(WebKit::WebWorkerBase::~WebWorkerBase):
(WebKit::WebWorkerBase::stopWorkerThread):
(WebKit::WebWorkerBase::initializeLoader):
(WebKit::WebWorkerBase::dispatchTaskToMainThread):
(WebKit::WebWorkerBase::invokeTaskMethod):
(WebKit::WebWorkerBase::postMessageToWorkerObject):
(WebKit::WebWorkerBase::postMessageTask):
(WebKit::WebWorkerBase::postExceptionToWorkerObject):
(WebKit::WebWorkerBase::postExceptionTask):
(WebKit::WebWorkerBase::postConsoleMessageToWorkerObject):
(WebKit::WebWorkerBase::postConsoleMessageTask):
(WebKit::WebWorkerBase::confirmMessageFromWorkerObject):
(WebKit::WebWorkerBase::confirmMessageTask):
(WebKit::WebWorkerBase::reportPendingActivity):
(WebKit::WebWorkerBase::reportPendingActivityTask):
(WebKit::WebWorkerBase::workerContextClosed):
(WebKit::WebWorkerBase::workerContextClosedTask):
(WebKit::WebWorkerBase::workerContextDestroyed):
(WebKit::WebWorkerBase::workerContextDestroyedTask):
(WebKit::WebWorkerBase::postTaskToLoader):
(WebKit::WebWorkerBase::postTaskForModeToWorkerContext):
* src/WebWorkerBase.h: Added.
(WebKit::WebWorkerBase::setWorkerThread):
(WebKit::WebWorkerBase::workerThread):
* src/WebWorkerClientImpl.cpp: Added.
(WebKit::WebWorkerClientImpl::createWorkerContextProxy):
(WebKit::WebWorkerClientImpl::WebWorkerClientImpl):
(WebKit::WebWorkerClientImpl::~WebWorkerClientImpl):
(WebKit::WebWorkerClientImpl::setWebWorker):
(WebKit::WebWorkerClientImpl::startWorkerContext):
(WebKit::WebWorkerClientImpl::terminateWorkerContext):
(WebKit::WebWorkerClientImpl::postMessageToWorkerContext):
(WebKit::WebWorkerClientImpl::hasPendingActivity):
(WebKit::WebWorkerClientImpl::workerObjectDestroyed):
(WebKit::WebWorkerClientImpl::postMessageToWorkerObject):
(WebKit::WebWorkerClientImpl::postExceptionToWorkerObject):
(WebKit::WebWorkerClientImpl::postConsoleMessageToWorkerObject):
(WebKit::WebWorkerClientImpl::confirmMessageFromWorkerObject):
(WebKit::WebWorkerClientImpl::reportPendingActivity):
(WebKit::WebWorkerClientImpl::workerContextDestroyed):
(WebKit::WebWorkerClientImpl::workerContextClosed):
(WebKit::WebWorkerClientImpl::startWorkerContextTask):
(WebKit::WebWorkerClientImpl::terminateWorkerContextTask):
(WebKit::WebWorkerClientImpl::postMessageToWorkerContextTask):
(WebKit::WebWorkerClientImpl::workerObjectDestroyedTask):
(WebKit::WebWorkerClientImpl::postMessageToWorkerObjectTask):
(WebKit::WebWorkerClientImpl::postExceptionToWorkerObjectTask):
(WebKit::WebWorkerClientImpl::postConsoleMessageToWorkerObjectTask):
(WebKit::WebWorkerClientImpl::confirmMessageFromWorkerObjectTask):
(WebKit::WebWorkerClientImpl::reportPendingActivityTask):
* src/WebWorkerClientImpl.h: Added.
(WebKit::WebWorkerClientImpl::createWorker):
(WebKit::WebWorkerClientImpl::notificationPresenter):
* src/WebWorkerImpl.cpp: Added.
(WebKit::WebWorker::create):
(WebKit::WebWorkerImpl::WebWorkerImpl):
(WebKit::WebWorkerImpl::~WebWorkerImpl):
(WebKit::WebWorkerImpl::commonClient):
(WebKit::WebWorkerImpl::postMessageToWorkerContextTask):
(WebKit::WebWorkerImpl::startWorkerContext):
(WebKit::WebWorkerImpl::terminateWorkerContext):
(WebKit::WebWorkerImpl::postMessageToWorkerContext):
(WebKit::WebWorkerImpl::workerObjectDestroyed):
(WebKit::WebWorkerImpl::clientDestroyed):
* src/WebWorkerImpl.h: Added.
(WebKit::WebWorkerImpl::client):
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@50751 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/WebKit/chromium/ChangeLog b/WebKit/chromium/ChangeLog
index 3560f77..a73eb32 100644
--- a/WebKit/chromium/ChangeLog
+++ b/WebKit/chromium/ChangeLog
@@ -2,6 +2,87 @@
Reviewed by Dimitri Glazkov.
+ Up-streaming Chromium API src files: WebWorker and friends.
+
+ https://bugs.webkit.org/show_bug.cgi?id=31276
+
+ * src/WebWorkerBase.cpp: Added.
+ (WebKit::WorkerWebFrameClient::didCreateDataSource):
+ (WebKit::WorkerWebFrameClient::sharedInstance):
+ (WebKit::WorkerWebFrameClient::WorkerWebFrameClient):
+ (WebKit::initializeWebKitStaticValues):
+ (WebKit::WebWorkerBase::WebWorkerBase):
+ (WebKit::WebWorkerBase::~WebWorkerBase):
+ (WebKit::WebWorkerBase::stopWorkerThread):
+ (WebKit::WebWorkerBase::initializeLoader):
+ (WebKit::WebWorkerBase::dispatchTaskToMainThread):
+ (WebKit::WebWorkerBase::invokeTaskMethod):
+ (WebKit::WebWorkerBase::postMessageToWorkerObject):
+ (WebKit::WebWorkerBase::postMessageTask):
+ (WebKit::WebWorkerBase::postExceptionToWorkerObject):
+ (WebKit::WebWorkerBase::postExceptionTask):
+ (WebKit::WebWorkerBase::postConsoleMessageToWorkerObject):
+ (WebKit::WebWorkerBase::postConsoleMessageTask):
+ (WebKit::WebWorkerBase::confirmMessageFromWorkerObject):
+ (WebKit::WebWorkerBase::confirmMessageTask):
+ (WebKit::WebWorkerBase::reportPendingActivity):
+ (WebKit::WebWorkerBase::reportPendingActivityTask):
+ (WebKit::WebWorkerBase::workerContextClosed):
+ (WebKit::WebWorkerBase::workerContextClosedTask):
+ (WebKit::WebWorkerBase::workerContextDestroyed):
+ (WebKit::WebWorkerBase::workerContextDestroyedTask):
+ (WebKit::WebWorkerBase::postTaskToLoader):
+ (WebKit::WebWorkerBase::postTaskForModeToWorkerContext):
+ * src/WebWorkerBase.h: Added.
+ (WebKit::WebWorkerBase::setWorkerThread):
+ (WebKit::WebWorkerBase::workerThread):
+ * src/WebWorkerClientImpl.cpp: Added.
+ (WebKit::WebWorkerClientImpl::createWorkerContextProxy):
+ (WebKit::WebWorkerClientImpl::WebWorkerClientImpl):
+ (WebKit::WebWorkerClientImpl::~WebWorkerClientImpl):
+ (WebKit::WebWorkerClientImpl::setWebWorker):
+ (WebKit::WebWorkerClientImpl::startWorkerContext):
+ (WebKit::WebWorkerClientImpl::terminateWorkerContext):
+ (WebKit::WebWorkerClientImpl::postMessageToWorkerContext):
+ (WebKit::WebWorkerClientImpl::hasPendingActivity):
+ (WebKit::WebWorkerClientImpl::workerObjectDestroyed):
+ (WebKit::WebWorkerClientImpl::postMessageToWorkerObject):
+ (WebKit::WebWorkerClientImpl::postExceptionToWorkerObject):
+ (WebKit::WebWorkerClientImpl::postConsoleMessageToWorkerObject):
+ (WebKit::WebWorkerClientImpl::confirmMessageFromWorkerObject):
+ (WebKit::WebWorkerClientImpl::reportPendingActivity):
+ (WebKit::WebWorkerClientImpl::workerContextDestroyed):
+ (WebKit::WebWorkerClientImpl::workerContextClosed):
+ (WebKit::WebWorkerClientImpl::startWorkerContextTask):
+ (WebKit::WebWorkerClientImpl::terminateWorkerContextTask):
+ (WebKit::WebWorkerClientImpl::postMessageToWorkerContextTask):
+ (WebKit::WebWorkerClientImpl::workerObjectDestroyedTask):
+ (WebKit::WebWorkerClientImpl::postMessageToWorkerObjectTask):
+ (WebKit::WebWorkerClientImpl::postExceptionToWorkerObjectTask):
+ (WebKit::WebWorkerClientImpl::postConsoleMessageToWorkerObjectTask):
+ (WebKit::WebWorkerClientImpl::confirmMessageFromWorkerObjectTask):
+ (WebKit::WebWorkerClientImpl::reportPendingActivityTask):
+ * src/WebWorkerClientImpl.h: Added.
+ (WebKit::WebWorkerClientImpl::createWorker):
+ (WebKit::WebWorkerClientImpl::notificationPresenter):
+ * src/WebWorkerImpl.cpp: Added.
+ (WebKit::WebWorker::create):
+ (WebKit::WebWorkerImpl::WebWorkerImpl):
+ (WebKit::WebWorkerImpl::~WebWorkerImpl):
+ (WebKit::WebWorkerImpl::commonClient):
+ (WebKit::WebWorkerImpl::postMessageToWorkerContextTask):
+ (WebKit::WebWorkerImpl::startWorkerContext):
+ (WebKit::WebWorkerImpl::terminateWorkerContext):
+ (WebKit::WebWorkerImpl::postMessageToWorkerContext):
+ (WebKit::WebWorkerImpl::workerObjectDestroyed):
+ (WebKit::WebWorkerImpl::clientDestroyed):
+ * src/WebWorkerImpl.h: Added.
+ (WebKit::WebWorkerImpl::client):
+
+2009-11-10 Yaar Schnitman <yaar at chromium.org>
+
+ Reviewed by Dimitri Glazkov.
+
Up-streaming Chromium API src files: Platform specific files.
https://bugs.webkit.org/show_bug.cgi?id=31276
diff --git a/WebKit/chromium/src/WebWorkerBase.cpp b/WebKit/chromium/src/WebWorkerBase.cpp
new file mode 100644
index 0000000..85a263b
--- /dev/null
+++ b/WebKit/chromium/src/WebWorkerBase.cpp
@@ -0,0 +1,308 @@
+/*
+ * 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"
+#include "WebWorkerBase.h"
+
+#include "GenericWorkerTask.h"
+#include "MessagePortChannel.h"
+#include "PlatformMessagePortChannel.h"
+
+#include "WebDataSourceImpl.h"
+#include "WebFrameClient.h"
+#include "WebFrameImpl.h"
+#include "WebMessagePortChannel.h"
+#include "WebView.h"
+#include "WebWorkerClient.h"
+
+#include "WorkerThread.h"
+#include <wtf/MainThread.h>
+
+using namespace WebCore;
+
+namespace WebKit {
+
+#if ENABLE(WORKERS)
+
+// Dummy WebViewDelegate - we only need it in Worker process to load a
+// 'shadow page' which will initialize WebCore loader.
+class WorkerWebFrameClient : public WebFrameClient {
+public:
+ // Tell the loader to load the data into the 'shadow page' synchronously,
+ // so we can grab the resulting Document right after load.
+ virtual void didCreateDataSource(WebFrame* frame, WebDataSource* ds)
+ {
+ static_cast<WebDataSourceImpl*>(ds)->setDeferMainResourceDataLoad(false);
+ }
+
+ // Lazy allocate and leak this instance.
+ static WorkerWebFrameClient* sharedInstance()
+ {
+ static WorkerWebFrameClient client;
+ return &client;
+ }
+
+private:
+ WorkerWebFrameClient()
+ {
+ }
+};
+
+// This function is called on the main thread to force to initialize some static
+// values used in WebKit before any worker thread is started. This is because in
+// our worker processs, we do not run any WebKit code in main thread and thus
+// when multiple workers try to start at the same time, we might hit crash due
+// to contention for initializing static values.
+static void initializeWebKitStaticValues()
+{
+ static bool initialized = false;
+ if (!initialized) {
+ initialized = true;
+ // Note that we have to pass a URL with valid protocol in order to follow
+ // the path to do static value initializations.
+ RefPtr<SecurityOrigin> origin =
+ SecurityOrigin::create(KURL(ParsedURLString, "http://localhost"));
+ origin.release();
+ }
+}
+
+WebWorkerBase::WebWorkerBase()
+ : m_webView(0)
+ , m_askedToTerminate(false)
+{
+ initializeWebKitStaticValues();
+}
+
+WebWorkerBase::~WebWorkerBase()
+{
+ ASSERT(m_webView);
+ m_webView->close();
+}
+
+void WebWorkerBase::stopWorkerThread()
+{
+ if (m_askedToTerminate)
+ return;
+ m_askedToTerminate = true;
+ if (m_workerThread)
+ m_workerThread->stop();
+}
+
+void WebWorkerBase::initializeLoader(const WebURL& url)
+{
+ // Create 'shadow page'. This page is never displayed, it is used to proxy the
+ // loading requests from the worker context to the rest of WebKit and Chromium
+ // infrastructure.
+ ASSERT(!m_webView);
+ m_webView = WebView::create(0);
+ m_webView->initializeMainFrame(WorkerWebFrameClient::sharedInstance());
+
+ WebFrameImpl* webFrame = static_cast<WebFrameImpl*>(m_webView->mainFrame());
+
+ // Construct substitute data source for the 'shadow page'. We only need it
+ // to have same origin as the worker so the loading checks work correctly.
+ CString content("");
+ int len = static_cast<int>(content.length());
+ RefPtr<SharedBuffer> buf(SharedBuffer::create(content.data(), len));
+ SubstituteData substData(buf, String("text/html"), String("UTF-8"), KURL());
+ ResourceRequest request(url, CString());
+ webFrame->frame()->loader()->load(request, substData, false);
+
+ // This document will be used as 'loading context' for the worker.
+ m_loadingDocument = webFrame->frame()->document();
+}
+
+void WebWorkerBase::dispatchTaskToMainThread(PassOwnPtr<ScriptExecutionContext::Task> task)
+{
+ return callOnMainThread(invokeTaskMethod, task.release());
+}
+
+void WebWorkerBase::invokeTaskMethod(void* param)
+{
+ ScriptExecutionContext::Task* task =
+ static_cast<ScriptExecutionContext::Task*>(param);
+ task->performTask(0);
+ delete task;
+}
+
+// WorkerObjectProxy -----------------------------------------------------------
+
+void WebWorkerBase::postMessageToWorkerObject(PassRefPtr<SerializedScriptValue> message,
+ PassOwnPtr<MessagePortChannelArray> channels)
+{
+ dispatchTaskToMainThread(createCallbackTask(&postMessageTask, this,
+ message->toString(), channels));
+}
+
+void WebWorkerBase::postMessageTask(ScriptExecutionContext* context,
+ WebWorkerBase* thisPtr,
+ String message,
+ PassOwnPtr<MessagePortChannelArray> channels)
+{
+ if (!thisPtr->client())
+ return;
+
+ WebMessagePortChannelArray webChannels(channels.get() ? channels->size() : 0);
+ for (size_t i = 0; i < webChannels.size(); ++i) {
+ webChannels[i] = (*channels)[i]->channel()->webChannelRelease();
+ webChannels[i]->setClient(0);
+ }
+
+ thisPtr->client()->postMessageToWorkerObject(message, webChannels);
+}
+
+void WebWorkerBase::postExceptionToWorkerObject(const String& errorMessage,
+ int lineNumber,
+ const String& sourceURL)
+{
+ dispatchTaskToMainThread(createCallbackTask(&postExceptionTask, this,
+ errorMessage, lineNumber,
+ sourceURL));
+}
+
+void WebWorkerBase::postExceptionTask(ScriptExecutionContext* context,
+ WebWorkerBase* thisPtr,
+ const String& errorMessage,
+ int lineNumber, const String& sourceURL)
+{
+ if (!thisPtr->commonClient())
+ return;
+
+ thisPtr->commonClient()->postExceptionToWorkerObject(errorMessage,
+ lineNumber,
+ sourceURL);
+}
+
+void WebWorkerBase::postConsoleMessageToWorkerObject(MessageDestination destination,
+ MessageSource source,
+ MessageType type,
+ MessageLevel level,
+ const String& message,
+ int lineNumber,
+ const String& sourceURL)
+{
+ dispatchTaskToMainThread(createCallbackTask(&postConsoleMessageTask, this,
+ static_cast<int>(destination),
+ static_cast<int>(source),
+ static_cast<int>(type),
+ static_cast<int>(level),
+ message, lineNumber, sourceURL));
+}
+
+void WebWorkerBase::postConsoleMessageTask(ScriptExecutionContext* context,
+ WebWorkerBase* thisPtr,
+ int destination, int source,
+ int type, int level,
+ const String& message,
+ int lineNumber,
+ const String& sourceURL)
+{
+ if (!thisPtr->commonClient())
+ return;
+ thisPtr->commonClient()->postConsoleMessageToWorkerObject(destination, source,
+ type, level, message,
+ lineNumber, sourceURL);
+}
+
+void WebWorkerBase::confirmMessageFromWorkerObject(bool hasPendingActivity)
+{
+ dispatchTaskToMainThread(createCallbackTask(&confirmMessageTask, this,
+ hasPendingActivity));
+}
+
+void WebWorkerBase::confirmMessageTask(ScriptExecutionContext* context,
+ WebWorkerBase* thisPtr,
+ bool hasPendingActivity)
+{
+ if (!thisPtr->client())
+ return;
+ thisPtr->client()->confirmMessageFromWorkerObject(hasPendingActivity);
+}
+
+void WebWorkerBase::reportPendingActivity(bool hasPendingActivity)
+{
+ dispatchTaskToMainThread(createCallbackTask(&reportPendingActivityTask,
+ this, hasPendingActivity));
+}
+
+void WebWorkerBase::reportPendingActivityTask(ScriptExecutionContext* context,
+ WebWorkerBase* thisPtr,
+ bool hasPendingActivity)
+{
+ if (!thisPtr->client())
+ return;
+ thisPtr->client()->reportPendingActivity(hasPendingActivity);
+}
+
+void WebWorkerBase::workerContextClosed()
+{
+ dispatchTaskToMainThread(createCallbackTask(&workerContextClosedTask,
+ this));
+}
+
+void WebWorkerBase::workerContextClosedTask(ScriptExecutionContext* context,
+ WebWorkerBase* thisPtr)
+{
+ if (thisPtr->commonClient())
+ thisPtr->commonClient()->workerContextClosed();
+}
+
+void WebWorkerBase::workerContextDestroyed()
+{
+ dispatchTaskToMainThread(createCallbackTask(&workerContextDestroyedTask,
+ this));
+}
+
+void WebWorkerBase::workerContextDestroyedTask(ScriptExecutionContext* context,
+ WebWorkerBase* thisPtr)
+{
+ if (thisPtr->commonClient())
+ thisPtr->commonClient()->workerContextDestroyed();
+ // The lifetime of this proxy is controlled by the worker context.
+ delete thisPtr;
+}
+
+// WorkerLoaderProxy -----------------------------------------------------------
+
+void WebWorkerBase::postTaskToLoader(PassOwnPtr<ScriptExecutionContext::Task> task)
+{
+ ASSERT(m_loadingDocument->isDocument());
+ m_loadingDocument->postTask(task);
+}
+
+void WebWorkerBase::postTaskForModeToWorkerContext(
+ PassOwnPtr<ScriptExecutionContext::Task> task, const String& mode)
+{
+ m_workerThread->runLoop().postTaskForMode(task, mode);
+}
+
+#endif // ENABLE(WORKERS)
+
+} // namespace WebKit
diff --git a/WebKit/chromium/src/WebWorkerBase.h b/WebKit/chromium/src/WebWorkerBase.h
new file mode 100644
index 0000000..0217401
--- /dev/null
+++ b/WebKit/chromium/src/WebWorkerBase.h
@@ -0,0 +1,149 @@
+/*
+ * 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 WebWorkerBase_h
+#define WebWorkerBase_h
+
+#if ENABLE(WORKERS)
+
+#include "ScriptExecutionContext.h"
+#include "WorkerLoaderProxy.h"
+#include "WorkerObjectProxy.h"
+#include <wtf/PassOwnPtr.h>
+#include <wtf/RefPtr.h>
+
+namespace WebCore {
+class WorkerThread;
+}
+
+namespace WebKit {
+class WebCommonWorkerClient;
+class WebURL;
+class WebView;
+class WebWorkerClient;
+
+// Base class for WebSharedWorkerImpl and WebWorkerImpl. It contains common
+// code used by both implementation classes, including implementations of the
+// WorkerObjectProxy and WorkerLoaderProxy interfaces.
+class WebWorkerBase : public WebCore::WorkerObjectProxy
+ , public WebCore::WorkerLoaderProxy {
+public:
+ WebWorkerBase();
+ virtual ~WebWorkerBase();
+
+ // WebCore::WorkerObjectProxy methods:
+ virtual void postMessageToWorkerObject(
+ PassRefPtr<WebCore::SerializedScriptValue>,
+ PassOwnPtr<WebCore::MessagePortChannelArray>);
+ virtual void postExceptionToWorkerObject(
+ const WebCore::String&, int, const WebCore::String&);
+ virtual void postConsoleMessageToWorkerObject(
+ WebCore::MessageDestination, WebCore::MessageSource, WebCore::MessageType,
+ WebCore::MessageLevel, const WebCore::String&, int, const WebCore::String&);
+ virtual void confirmMessageFromWorkerObject(bool);
+ virtual void reportPendingActivity(bool);
+ virtual void workerContextClosed();
+ virtual void workerContextDestroyed();
+
+ // WebCore::WorkerLoaderProxy methods:
+ virtual void postTaskToLoader(PassOwnPtr<WebCore::ScriptExecutionContext::Task>);
+ virtual void postTaskForModeToWorkerContext(
+ PassOwnPtr<WebCore::ScriptExecutionContext::Task>, const WebCore::String& mode);
+
+ // Executes the given task on the main thread.
+ static void dispatchTaskToMainThread(PassOwnPtr<WebCore::ScriptExecutionContext::Task>);
+
+protected:
+ virtual WebWorkerClient* client() = 0;
+ virtual WebCommonWorkerClient* commonClient() = 0;
+
+ void setWorkerThread(PassRefPtr<WebCore::WorkerThread> thread) { m_workerThread = thread; }
+ WebCore::WorkerThread* workerThread() { return m_workerThread.get(); }
+
+ // Shuts down the worker thread.
+ void stopWorkerThread();
+
+ // Creates the shadow loader used for worker network requests.
+ void initializeLoader(const WebURL&);
+
+private:
+ // Function used to invoke tasks on the main thread.
+ static void invokeTaskMethod(void*);
+
+ // Tasks that are run on the main thread.
+ static void postMessageTask(
+ WebCore::ScriptExecutionContext* context,
+ WebWorkerBase* thisPtr,
+ WebCore::String message,
+ PassOwnPtr<WebCore::MessagePortChannelArray> channels);
+ static void postExceptionTask(
+ WebCore::ScriptExecutionContext* context,
+ WebWorkerBase* thisPtr,
+ const WebCore::String& message,
+ int lineNumber,
+ const WebCore::String& sourceURL);
+ static void postConsoleMessageTask(
+ WebCore::ScriptExecutionContext* context,
+ WebWorkerBase* thisPtr,
+ int destination,
+ int source,
+ int type,
+ int level,
+ const WebCore::String& message,
+ int lineNumber,
+ const WebCore::String& sourceURL);
+ static void confirmMessageTask(
+ WebCore::ScriptExecutionContext* context,
+ WebWorkerBase* thisPtr,
+ bool hasPendingActivity);
+ static void reportPendingActivityTask(
+ WebCore::ScriptExecutionContext* context,
+ WebWorkerBase* thisPtr,
+ bool hasPendingActivity);
+ static void workerContextClosedTask(
+ WebCore::ScriptExecutionContext* context,
+ WebWorkerBase* thisPtr);
+ static void workerContextDestroyedTask(
+ WebCore::ScriptExecutionContext* context,
+ WebWorkerBase* thisPtr);
+
+ // 'shadow page' - created to proxy loading requests from the worker.
+ RefPtr<WebCore::ScriptExecutionContext> m_loadingDocument;
+ WebView* m_webView;
+ bool m_askedToTerminate;
+
+ RefPtr<WebCore::WorkerThread> m_workerThread;
+};
+
+} // namespace WebKit
+
+#endif // ENABLE(WORKERS)
+
+#endif
diff --git a/WebKit/chromium/src/WebWorkerClientImpl.cpp b/WebKit/chromium/src/WebWorkerClientImpl.cpp
new file mode 100644
index 0000000..6be03a7
--- /dev/null
+++ b/WebKit/chromium/src/WebWorkerClientImpl.cpp
@@ -0,0 +1,416 @@
+/*
+ * 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"
+#include "WebWorkerClientImpl.h"
+
+#if ENABLE(WORKERS)
+
+#include "DedicatedWorkerThread.h"
+#include "ErrorEvent.h"
+#include "Frame.h"
+#include "FrameLoaderClient.h"
+#include "GenericWorkerTask.h"
+#include "MessageEvent.h"
+#include "MessagePort.h"
+#include "MessagePortChannel.h"
+#include "ScriptExecutionContext.h"
+#include "Worker.h"
+#include "WorkerContext.h"
+#include "WorkerContextExecutionProxy.h"
+#include "WorkerMessagingProxy.h"
+#include <wtf/Threading.h>
+
+#include "FrameLoaderClientImpl.h"
+#include "PlatformMessagePortChannel.h"
+#include "WebFrameClient.h"
+#include "WebFrameImpl.h"
+#include "WebKit.h"
+#include "WebKitClient.h"
+#include "WebMessagePortChannel.h"
+#include "WebString.h"
+#include "WebURL.h"
+#include "WebViewImpl.h"
+#include "WebWorker.h"
+#include "WebWorkerImpl.h"
+
+using namespace WebCore;
+
+namespace WebKit {
+
+// When WebKit creates a WorkerContextProxy object, we check if we're in the
+// renderer or worker process. If the latter, then we just use
+// WorkerMessagingProxy.
+//
+// If we're in the renderer process, then we need use the glue provided
+// WebWorker object to talk to the worker process over IPC. The worker process
+// talks to Worker* using WorkerObjectProxy, which we implement on
+// WebWorkerClientImpl.
+//
+// Note that if we're running each worker in a separate process, then nested
+// workers end up using the same codepath as the renderer process.
+
+// static
+WorkerContextProxy* WebWorkerClientImpl::createWorkerContextProxy(Worker* worker)
+{
+ // Special behavior for multiple workers per process.
+ // FIXME: v8 doesn't support more than one workers per process.
+ // if (!worker->scriptExecutionContext()->isDocument())
+ // return new WorkerMessagingProxy(worker);
+
+ WebWorker* webWorker = 0;
+ WebWorkerClientImpl* proxy = new WebWorkerClientImpl(worker);
+
+ if (worker->scriptExecutionContext()->isDocument()) {
+ Document* document = static_cast<Document*>(
+ worker->scriptExecutionContext());
+ WebFrameImpl* webFrame = WebFrameImpl::fromFrame(document->frame());
+ webWorker = webFrame->client()->createWorker(webFrame, proxy);
+ } else {
+ WorkerContextExecutionProxy* currentContext =
+ WorkerContextExecutionProxy::retrieve();
+ if (!currentContext) {
+ ASSERT_NOT_REACHED();
+ return 0;
+ }
+
+ DedicatedWorkerThread* thread =
+ static_cast<DedicatedWorkerThread*>(currentContext->workerContext()->thread());
+ WorkerObjectProxy* workerObjectProxy = &thread->workerObjectProxy();
+ WebWorkerImpl* impl = reinterpret_cast<WebWorkerImpl*>(workerObjectProxy);
+ webWorker = impl->client()->createWorker(proxy);
+ }
+
+ proxy->setWebWorker(webWorker);
+ return proxy;
+}
+
+WebWorkerClientImpl::WebWorkerClientImpl(Worker* worker)
+ : m_scriptExecutionContext(worker->scriptExecutionContext())
+ , m_worker(worker)
+ , m_askedToTerminate(false)
+ , m_unconfirmedMessageCount(0)
+ , m_workerContextHadPendingActivity(false)
+ , m_workerThreadId(currentThread())
+{
+}
+
+WebWorkerClientImpl::~WebWorkerClientImpl()
+{
+}
+
+void WebWorkerClientImpl::setWebWorker(WebWorker* webWorker)
+{
+ m_webWorker = webWorker;
+}
+
+void WebWorkerClientImpl::startWorkerContext(const KURL& scriptURL,
+ const String& userAgent,
+ const String& sourceCode)
+{
+ // Worker.terminate() could be called from JS before the context is started.
+ if (m_askedToTerminate)
+ return;
+ if (!isMainThread()) {
+ WebWorkerBase::dispatchTaskToMainThread(createCallbackTask(
+ &startWorkerContextTask,
+ this,
+ scriptURL.string(),
+ userAgent,
+ sourceCode));
+ return;
+ }
+ m_webWorker->startWorkerContext(scriptURL, userAgent, sourceCode);
+}
+
+void WebWorkerClientImpl::terminateWorkerContext()
+{
+ if (m_askedToTerminate)
+ return;
+ m_askedToTerminate = true;
+ if (!isMainThread()) {
+ WebWorkerBase::dispatchTaskToMainThread(createCallbackTask(&terminateWorkerContextTask, this));
+ return;
+ }
+ m_webWorker->terminateWorkerContext();
+}
+
+void WebWorkerClientImpl::postMessageToWorkerContext(
+ PassRefPtr<SerializedScriptValue> message,
+ PassOwnPtr<MessagePortChannelArray> channels)
+{
+ // Worker.terminate() could be called from JS before the context is started.
+ if (m_askedToTerminate)
+ return;
+ ++m_unconfirmedMessageCount;
+ if (!isMainThread()) {
+ WebWorkerBase::dispatchTaskToMainThread(createCallbackTask(&postMessageToWorkerContextTask,
+ this,
+ message->toString(),
+ channels));
+ return;
+ }
+ WebMessagePortChannelArray webChannels(channels.get() ? channels->size() : 0);
+ for (size_t i = 0; i < webChannels.size(); ++i) {
+ WebMessagePortChannel* webchannel =
+ (*channels)[i]->channel()->webChannelRelease();
+ webchannel->setClient(0);
+ webChannels[i] = webchannel;
+ }
+ m_webWorker->postMessageToWorkerContext(message->toString(), webChannels);
+}
+
+bool WebWorkerClientImpl::hasPendingActivity() const
+{
+ return !m_askedToTerminate
+ && (m_unconfirmedMessageCount || m_workerContextHadPendingActivity);
+}
+
+void WebWorkerClientImpl::workerObjectDestroyed()
+{
+ if (isMainThread()) {
+ m_webWorker->workerObjectDestroyed();
+ m_worker = 0;
+ }
+ // Even if this is called on the main thread, there could be a queued task for
+ // this object, so don't delete it right away.
+ WebWorkerBase::dispatchTaskToMainThread(createCallbackTask(&workerObjectDestroyedTask,
+ this));
+}
+
+void WebWorkerClientImpl::postMessageToWorkerObject(const WebString& message,
+ const WebMessagePortChannelArray& channels)
+{
+ OwnPtr<MessagePortChannelArray> channels2;
+ if (channels.size()) {
+ channels2 = new MessagePortChannelArray(channels.size());
+ for (size_t i = 0; i < channels.size(); ++i) {
+ RefPtr<PlatformMessagePortChannel> platform_channel =
+ PlatformMessagePortChannel::create(channels[i]);
+ channels[i]->setClient(platform_channel.get());
+ (*channels2)[i] = MessagePortChannel::create(platform_channel);
+ }
+ }
+
+ if (currentThread() != m_workerThreadId) {
+ m_scriptExecutionContext->postTask(createCallbackTask(&postMessageToWorkerObjectTask,
+ this,
+ String(message),
+ channels2.release()));
+ return;
+ }
+
+ postMessageToWorkerObjectTask(m_scriptExecutionContext.get(), this,
+ message, channels2.release());
+}
+
+void WebWorkerClientImpl::postExceptionToWorkerObject(const WebString& errorMessage,
+ int lineNumber,
+ const WebString& sourceURL)
+{
+ if (currentThread() != m_workerThreadId) {
+ m_scriptExecutionContext->postTask(createCallbackTask(&postExceptionToWorkerObjectTask,
+ this,
+ String(errorMessage),
+ lineNumber,
+ String(sourceURL)));
+ return;
+ }
+
+ bool handled = false;
+ handled = m_worker->dispatchEvent(ErrorEvent::create(errorMessage,
+ sourceURL,
+ lineNumber));
+ if (!handled)
+ m_scriptExecutionContext->reportException(errorMessage, lineNumber, sourceURL);
+}
+
+void WebWorkerClientImpl::postConsoleMessageToWorkerObject(int destinationId,
+ int sourceId,
+ int messageType,
+ int messageLevel,
+ const WebString& message,
+ int lineNumber,
+ const WebString& sourceURL)
+{
+ if (currentThread() != m_workerThreadId) {
+ m_scriptExecutionContext->postTask(createCallbackTask(&postConsoleMessageToWorkerObjectTask,
+ this,
+ destinationId,
+ sourceId,
+ messageType,
+ messageLevel,
+ String(message),
+ lineNumber,
+ String(sourceURL)));
+ return;
+ }
+
+ m_scriptExecutionContext->addMessage(static_cast<MessageDestination>(destinationId),
+ static_cast<MessageSource>(sourceId),
+ static_cast<MessageType>(messageType),
+ static_cast<MessageLevel>(messageLevel),
+ String(message), lineNumber,
+ String(sourceURL));
+}
+
+void WebWorkerClientImpl::confirmMessageFromWorkerObject(bool hasPendingActivity)
+{
+ // unconfirmed_message_count_ can only be updated on the thread where it's
+ // accessed. Otherwise there are race conditions with v8's garbage
+ // collection.
+ m_scriptExecutionContext->postTask(createCallbackTask(&confirmMessageFromWorkerObjectTask,
+ this));
+}
+
+void WebWorkerClientImpl::reportPendingActivity(bool hasPendingActivity)
+{
+ // See above comment in confirmMessageFromWorkerObject.
+ m_scriptExecutionContext->postTask(createCallbackTask(&reportPendingActivityTask,
+ this,
+ hasPendingActivity));
+}
+
+void WebWorkerClientImpl::workerContextDestroyed()
+{
+}
+
+void WebWorkerClientImpl::workerContextClosed()
+{
+}
+
+void WebWorkerClientImpl::startWorkerContextTask(ScriptExecutionContext* context,
+ WebWorkerClientImpl* thisPtr,
+ const String& scriptURL,
+ const String& userAgent,
+ const String& sourceCode)
+{
+ thisPtr->m_webWorker->startWorkerContext(KURL(ParsedURLString, scriptURL),
+ userAgent, sourceCode);
+}
+
+void WebWorkerClientImpl::terminateWorkerContextTask(ScriptExecutionContext* context,
+ WebWorkerClientImpl* thisPtr)
+{
+ thisPtr->m_webWorker->terminateWorkerContext();
+}
+
+void WebWorkerClientImpl::postMessageToWorkerContextTask(ScriptExecutionContext* context,
+ WebWorkerClientImpl* thisPtr,
+ const String& message,
+ PassOwnPtr<MessagePortChannelArray> channels)
+{
+ WebMessagePortChannelArray webChannels(channels.get() ? channels->size() : 0);
+
+ for (size_t i = 0; i < webChannels.size(); ++i) {
+ webChannels[i] = (*channels)[i]->channel()->webChannelRelease();
+ webChannels[i]->setClient(0);
+ }
+
+ thisPtr->m_webWorker->postMessageToWorkerContext(message, webChannels);
+}
+
+void WebWorkerClientImpl::workerObjectDestroyedTask(ScriptExecutionContext* context,
+ WebWorkerClientImpl* thisPtr)
+{
+ if (thisPtr->m_worker) // Check we haven't alread called this.
+ thisPtr->m_webWorker->workerObjectDestroyed();
+ delete thisPtr;
+}
+
+void WebWorkerClientImpl::postMessageToWorkerObjectTask(
+ ScriptExecutionContext* context,
+ WebWorkerClientImpl* thisPtr,
+ const String& message,
+ PassOwnPtr<MessagePortChannelArray> channels)
+{
+
+ if (thisPtr->m_worker) {
+ OwnPtr<MessagePortArray> ports =
+ MessagePort::entanglePorts(*context, channels.release());
+ RefPtr<SerializedScriptValue> serializedMessage =
+ SerializedScriptValue::create(message);
+ thisPtr->m_worker->dispatchEvent(MessageEvent::create(ports.release(),
+ serializedMessage.release()));
+ }
+}
+
+void WebWorkerClientImpl::postExceptionToWorkerObjectTask(
+ ScriptExecutionContext* context,
+ WebWorkerClientImpl* thisPtr,
+ const String& errorMessage,
+ int lineNumber,
+ const String& sourceURL)
+{
+ bool handled = false;
+ if (thisPtr->m_worker)
+ handled = thisPtr->m_worker->dispatchEvent(ErrorEvent::create(errorMessage,
+ sourceURL,
+ lineNumber));
+ if (!handled)
+ thisPtr->m_scriptExecutionContext->reportException(errorMessage,
+ lineNumber,
+ sourceURL);
+}
+
+void WebWorkerClientImpl::postConsoleMessageToWorkerObjectTask(ScriptExecutionContext* context,
+ WebWorkerClientImpl* thisPtr,
+ int destinationId,
+ int sourceId,
+ int messageType,
+ int messageLevel,
+ const String& message,
+ int lineNumber,
+ const String& sourceURL)
+{
+ thisPtr->m_scriptExecutionContext->addMessage(static_cast<MessageDestination>(destinationId),
+ static_cast<MessageSource>(sourceId),
+ static_cast<MessageType>(messageType),
+ static_cast<MessageLevel>(messageLevel),
+ message, lineNumber,
+ sourceURL);
+}
+
+void WebWorkerClientImpl::confirmMessageFromWorkerObjectTask(ScriptExecutionContext* context,
+ WebWorkerClientImpl* thisPtr)
+{
+ thisPtr->m_unconfirmedMessageCount--;
+}
+
+void WebWorkerClientImpl::reportPendingActivityTask(ScriptExecutionContext* context,
+ WebWorkerClientImpl* thisPtr,
+ bool hasPendingActivity)
+{
+ thisPtr->m_workerContextHadPendingActivity = hasPendingActivity;
+}
+
+} // namespace WebKit
+
+#endif
diff --git a/WebKit/chromium/src/WebWorkerClientImpl.h b/WebKit/chromium/src/WebWorkerClientImpl.h
new file mode 100644
index 0000000..63acebc
--- /dev/null
+++ b/WebKit/chromium/src/WebWorkerClientImpl.h
@@ -0,0 +1,156 @@
+/*
+ * 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 WebWorkerClientImpl_h
+#define WebWorkerClientImpl_h
+
+#if ENABLE(WORKERS)
+
+// FIXME: fix to just "WebWorkerClient.h" once nobody in glue depends on us.
+#include "../public/WebWorkerClient.h"
+
+#include "WorkerContextProxy.h"
+#include <wtf/PassOwnPtr.h>
+#include <wtf/RefPtr.h>
+
+namespace WebCore {
+class ScriptExecutionContext;
+}
+
+namespace WebKit {
+class WebWorker;
+
+// The purpose of this class is to provide a WorkerContextProxy
+// implementation that we can give to WebKit. Internally, it converts the
+// data types to Chrome compatible ones so that renderer code can use it over
+// IPC.
+class WebWorkerClientImpl : public WebCore::WorkerContextProxy
+ , public WebWorkerClient {
+public:
+ WebWorkerClientImpl(WebCore::Worker*);
+
+ // WebCore::WorkerContextProxy Factory.
+ static WebCore::WorkerContextProxy* createWorkerContextProxy(WebCore::Worker*);
+ void setWebWorker(WebWorker*);
+
+ // WebCore::WorkerContextProxy methods:
+ // These are called on the thread that created the worker. In the renderer
+ // process, this will be the main WebKit thread. In the worker process, this
+ // will be the thread of the executing worker (not the main WebKit thread).
+ virtual void startWorkerContext(const WebCore::KURL&,
+ const WebCore::String&,
+ const WebCore::String&);
+ virtual void terminateWorkerContext();
+ virtual void postMessageToWorkerContext(
+ PassRefPtr<WebCore::SerializedScriptValue> message,
+ PassOwnPtr<WebCore::MessagePortChannelArray> channels);
+ virtual bool hasPendingActivity() const;
+ virtual void workerObjectDestroyed();
+
+ // WebWorkerClient methods:
+ // These are called on the main WebKit thread.
+ virtual void postMessageToWorkerObject(const WebString&, const WebMessagePortChannelArray&);
+ virtual void postExceptionToWorkerObject(const WebString&, int, const WebString&);
+ virtual void postConsoleMessageToWorkerObject(int, int, int, int, const WebString&,
+ int, const WebString&);
+ virtual void confirmMessageFromWorkerObject(bool);
+ virtual void reportPendingActivity(bool);
+ virtual void workerContextClosed();
+ virtual void workerContextDestroyed();
+ virtual WebWorker* createWorker(WebWorkerClient*) { return 0; }
+ virtual WebNotificationPresenter* notificationPresenter()
+ {
+ // FIXME: Notifications not yet supported in workers.
+ return 0;
+ }
+
+private:
+ virtual ~WebWorkerClientImpl();
+
+ // Methods used to support WebWorkerClientImpl being constructed on worker
+ // threads.
+ // These tasks are dispatched on the WebKit thread.
+ static void startWorkerContextTask(WebCore::ScriptExecutionContext* context,
+ WebWorkerClientImpl* thisPtr,
+ const WebCore::String& scriptURL,
+ const WebCore::String& userAgent,
+ const WebCore::String& sourceCode);
+ static void terminateWorkerContextTask(WebCore::ScriptExecutionContext* context,
+ WebWorkerClientImpl* thisPtr);
+ static void postMessageToWorkerContextTask(WebCore::ScriptExecutionContext* context,
+ WebWorkerClientImpl* thisPtr,
+ const WebCore::String& message,
+ PassOwnPtr<WebCore::MessagePortChannelArray> channels);
+ static void workerObjectDestroyedTask(WebCore::ScriptExecutionContext* context,
+ WebWorkerClientImpl* thisPtr);
+
+ // These tasks are dispatched on the thread that created the worker (i.e.
+ // main WebKit thread in renderer process, and the worker thread in the
+ // worker process).
+ static void postMessageToWorkerObjectTask(WebCore::ScriptExecutionContext* context,
+ WebWorkerClientImpl* thisPtr,
+ const WebCore::String& message,
+ PassOwnPtr<WebCore::MessagePortChannelArray> channels);
+ static void postExceptionToWorkerObjectTask(WebCore::ScriptExecutionContext* context,
+ WebWorkerClientImpl* thisPtr,
+ const WebCore::String& message,
+ int lineNumber,
+ const WebCore::String& sourceURL);
+ static void postConsoleMessageToWorkerObjectTask(WebCore::ScriptExecutionContext* context,
+ WebWorkerClientImpl* thisPtr,
+ int destinationId,
+ int sourceId,
+ int messageType,
+ int messageLevel,
+ const WebCore::String& message,
+ int lineNumber,
+ const WebCore::String& sourceURL);
+ static void confirmMessageFromWorkerObjectTask(WebCore::ScriptExecutionContext* context,
+ WebWorkerClientImpl* thisPtr);
+ static void reportPendingActivityTask(WebCore::ScriptExecutionContext* context,
+ WebWorkerClientImpl* thisPtr,
+ bool hasPendingActivity);
+
+ // Guard against context from being destroyed before a worker exits.
+ RefPtr<WebCore::ScriptExecutionContext> m_scriptExecutionContext;
+
+ WebCore::Worker* m_worker;
+ WebWorker* m_webWorker;
+ bool m_askedToTerminate;
+ unsigned m_unconfirmedMessageCount;
+ bool m_workerContextHadPendingActivity;
+ ThreadIdentifier m_workerThreadId;
+};
+
+} // namespace WebKit;
+
+#endif // ENABLE(WORKERS)
+
+#endif
diff --git a/WebKit/chromium/src/WebWorkerImpl.cpp b/WebKit/chromium/src/WebWorkerImpl.cpp
new file mode 100644
index 0000000..744be30
--- /dev/null
+++ b/WebKit/chromium/src/WebWorkerImpl.cpp
@@ -0,0 +1,158 @@
+/*
+ * 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"
+#include "WebWorkerImpl.h"
+
+#include "DedicatedWorkerContext.h"
+#include "DedicatedWorkerThread.h"
+#include "GenericWorkerTask.h"
+#include "KURL.h"
+#include "MessageEvent.h"
+#include "MessagePort.h"
+#include "MessagePortChannel.h"
+#include "ScriptExecutionContext.h"
+#include "SecurityOrigin.h"
+#include "SerializedScriptValue.h"
+#include "SubstituteData.h"
+#include <wtf/Threading.h>
+
+#include "PlatformMessagePortChannel.h"
+#include "WebMessagePortChannel.h"
+#include "WebString.h"
+#include "WebURL.h"
+#include "WebWorkerClient.h"
+
+using namespace WebCore;
+
+namespace WebKit {
+
+#if ENABLE(WORKERS)
+
+WebWorker* WebWorker::create(WebWorkerClient* client)
+{
+ return new WebWorkerImpl(client);
+}
+
+
+WebWorkerImpl::WebWorkerImpl(WebWorkerClient* client)
+ : m_client(client)
+{
+}
+
+WebWorkerImpl::~WebWorkerImpl()
+{
+}
+
+WebCommonWorkerClient* WebWorkerImpl::commonClient()
+{
+ return m_client;
+}
+
+void WebWorkerImpl::postMessageToWorkerContextTask(WebCore::ScriptExecutionContext* context,
+ WebWorkerImpl* thisPtr,
+ const String& message,
+ PassOwnPtr<MessagePortChannelArray> channels)
+{
+ ASSERT(context->isWorkerContext());
+ DedicatedWorkerContext* workerContext =
+ static_cast<DedicatedWorkerContext*>(context);
+
+ OwnPtr<MessagePortArray> ports =
+ MessagePort::entanglePorts(*context, channels.release());
+ RefPtr<SerializedScriptValue> serializedMessage =
+ SerializedScriptValue::create(message);
+ workerContext->dispatchEvent(MessageEvent::create(
+ ports.release(), serializedMessage.release()));
+ thisPtr->confirmMessageFromWorkerObject(workerContext->hasPendingActivity());
+}
+
+// WebWorker -------------------------------------------------------------------
+
+void WebWorkerImpl::startWorkerContext(const WebURL& scriptUrl,
+ const WebString& userAgent,
+ const WebString& sourceCode)
+{
+ initializeLoader(scriptUrl);
+ setWorkerThread(DedicatedWorkerThread::create(scriptUrl, userAgent,
+ sourceCode, *this, *this));
+ // Worker initialization means a pending activity.
+ reportPendingActivity(true);
+ workerThread()->start();
+}
+
+void WebWorkerImpl::terminateWorkerContext()
+{
+ stopWorkerThread();
+}
+
+void WebWorkerImpl::postMessageToWorkerContext(const WebString& message,
+ const WebMessagePortChannelArray& webChannels)
+{
+ OwnPtr<MessagePortChannelArray> channels;
+ if (webChannels.size()) {
+ channels = new MessagePortChannelArray(webChannels.size());
+ for (size_t i = 0; i < webChannels.size(); ++i) {
+ RefPtr<PlatformMessagePortChannel> platform_channel =
+ PlatformMessagePortChannel::create(webChannels[i]);
+ webChannels[i]->setClient(platform_channel.get());
+ (*channels)[i] = MessagePortChannel::create(platform_channel);
+ }
+ }
+
+ workerThread()->runLoop().postTask(
+ createCallbackTask(&postMessageToWorkerContextTask,
+ this, String(message), channels.release()));
+}
+
+void WebWorkerImpl::workerObjectDestroyed()
+{
+ // Worker object in the renderer was destroyed, perhaps a result of GC.
+ // For us, it's a signal to start terminating the WorkerContext too.
+ // FIXME: when 'kill a worker' html5 spec algorithm is implemented, it
+ // should be used here instead of 'terminate a worker'.
+ terminateWorkerContext();
+}
+
+void WebWorkerImpl::clientDestroyed()
+{
+ m_client = 0;
+}
+
+#else
+
+WebWorker* WebWorker::create(WebWorkerClient* client)
+{
+ return 0;
+}
+
+#endif // ENABLE(WORKERS)
+
+} // namespace WebKit
diff --git a/WebKit/chromium/src/WebWorkerImpl.h b/WebKit/chromium/src/WebWorkerImpl.h
new file mode 100644
index 0000000..bec96cd
--- /dev/null
+++ b/WebKit/chromium/src/WebWorkerImpl.h
@@ -0,0 +1,83 @@
+/*
+ * 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 WebWorkerImpl_h
+#define WebWorkerImpl_h
+
+#include "WebWorker.h"
+
+#if ENABLE(WORKERS)
+
+#include "ScriptExecutionContext.h"
+
+#include "WebWorkerBase.h"
+
+namespace WebKit {
+class WebView;
+
+// This class is used by the worker process code to talk to the WebCore::Worker
+// implementation. It can't use it directly since it uses WebKit types, so this
+// class converts the data types. When the WebCore::Worker object wants to call
+// WebCore::WorkerObjectProxy, this class will conver to Chrome data types first
+// and then call the supplied WebWorkerClient.
+class WebWorkerImpl : public WebWorkerBase, public WebWorker {
+public:
+ explicit WebWorkerImpl(WebWorkerClient* client);
+
+ // WebWorker methods:
+ virtual void startWorkerContext(const WebURL&, const WebString&, const WebString&);
+ virtual void terminateWorkerContext();
+ virtual void postMessageToWorkerContext(const WebString&, const WebMessagePortChannelArray&);
+ virtual void workerObjectDestroyed();
+ virtual void clientDestroyed();
+
+ // WebWorkerBase methods:
+ virtual WebWorkerClient* client() { return m_client; }
+ virtual WebCommonWorkerClient* commonClient();
+
+private:
+ virtual ~WebWorkerImpl();
+
+ // Tasks that are run on the worker thread.
+ static void postMessageToWorkerContextTask(
+ WebCore::ScriptExecutionContext* context,
+ WebWorkerImpl* thisPtr,
+ const WebCore::String& message,
+ PassOwnPtr<WebCore::MessagePortChannelArray> channels);
+
+ WebWorkerClient* m_client;
+
+};
+
+} // namespace WebKit
+
+#endif // ENABLE(WORKERS)
+
+#endif
--
WebKit Debian packaging
More information about the Pkg-webkit-commits
mailing list