diff options
23 files changed, 638 insertions, 349 deletions
diff --git a/chrome/renderer/render_view.cc b/chrome/renderer/render_view.cc index c4af4c9..fc74190 100644 --- a/chrome/renderer/render_view.cc +++ b/chrome/renderer/render_view.cc @@ -56,6 +56,7 @@ #include "chrome/renderer/visitedlink_slave.h" #include "chrome/renderer/webplugin_delegate_pepper.h" #include "chrome/renderer/webplugin_delegate_proxy.h" +#include "chrome/renderer/websharedworker_proxy.h" #include "chrome/renderer/webworker_proxy.h" #include "grit/generated_resources.h" #include "grit/renderer_resources.h" @@ -148,6 +149,7 @@ using WebKit::WebScriptSource; using WebKit::WebSearchableFormData; using WebKit::WebSecurityOrigin; using WebKit::WebSettings; +using WebKit::WebSharedWorker; using WebKit::WebSize; using WebKit::WebString; using WebKit::WebTextAffinity; @@ -1783,6 +1785,17 @@ WebWorker* RenderView::createWorker(WebFrame* frame, WebWorkerClient* client) { return new WebWorkerProxy(client, RenderThread::current(), routing_id_); } +WebSharedWorker* RenderView::createSharedWorker( + WebFrame* frame, const WebURL& url, const WebString& name, + unsigned long long documentId) { + + // TODO(atwilson): Call to the browser process to check if there's an existing + // worker (passing MSG_ROUTING_NONE for now, to indicate no existing worker). + int worker_route_id = MSG_ROUTING_NONE; + return new WebSharedWorkerProxy( + RenderThread::current(), worker_route_id, routing_id_); +} + WebMediaPlayer* RenderView::createMediaPlayer( WebFrame* frame, WebMediaPlayerClient* client) { scoped_refptr<media::FilterFactoryCollection> factory = diff --git a/chrome/renderer/render_view.h b/chrome/renderer/render_view.h index f162b99..3991da9 100644 --- a/chrome/renderer/render_view.h +++ b/chrome/renderer/render_view.h @@ -261,6 +261,9 @@ class RenderView : public RenderWidget, WebKit::WebFrame* frame, const WebKit::WebPluginParams& params); virtual WebKit::WebWorker* createWorker( WebKit::WebFrame* frame, WebKit::WebWorkerClient* client); + virtual WebKit::WebSharedWorker* createSharedWorker( + WebKit::WebFrame* frame, const WebKit::WebURL& url, + const WebKit::WebString& name, unsigned long long documentId); virtual WebKit::WebMediaPlayer* createMediaPlayer( WebKit::WebFrame* frame, WebKit::WebMediaPlayerClient* client); virtual void willClose(WebKit::WebFrame* frame); diff --git a/chrome/renderer/websharedworker_proxy.cc b/chrome/renderer/websharedworker_proxy.cc index ee08901..c0ecba4 100644 --- a/chrome/renderer/websharedworker_proxy.cc +++ b/chrome/renderer/websharedworker_proxy.cc @@ -10,8 +10,8 @@ #include "webkit/api/public/WebURL.h" WebSharedWorkerProxy::WebSharedWorkerProxy(ChildThread* child_thread, - int route_id, - int render_view_route_id) + int route_id, + int render_view_route_id) : WebWorkerBase(child_thread, route_id, render_view_route_id) { } @@ -27,6 +27,16 @@ void WebSharedWorkerProxy::startWorkerContext( CreateWorkerContext(script_url, true, name, user_agent, source_code); } +void WebSharedWorkerProxy::terminateWorkerContext() { + // This API should only be invoked from worker context. + NOTREACHED(); +} + +void WebSharedWorkerProxy::clientDestroyed() { + // This API should only be invoked from worker context. + NOTREACHED(); +} + void WebSharedWorkerProxy::connect(WebKit::WebMessagePortChannel* channel) { WebMessagePortChannelImpl* webchannel = static_cast<WebMessagePortChannelImpl*>(channel); diff --git a/chrome/renderer/websharedworker_proxy.h b/chrome/renderer/websharedworker_proxy.h index 8ffe63c..b9ab065 100644 --- a/chrome/renderer/websharedworker_proxy.h +++ b/chrome/renderer/websharedworker_proxy.h @@ -21,8 +21,8 @@ class WebSharedWorkerProxy : public WebKit::WebSharedWorker, private WebWorkerBase { public: WebSharedWorkerProxy(ChildThread* child_thread, - int route_id, - int render_view_route_id); + int route_id, + int render_view_route_id); // Implementations of WebSharedWorker APIs virtual bool isStarted(); @@ -31,6 +31,8 @@ class WebSharedWorkerProxy : public WebKit::WebSharedWorker, const WebKit::WebString& name, const WebKit::WebString& user_agent, const WebKit::WebString& source_code); + virtual void terminateWorkerContext(); + virtual void clientDestroyed(); // IPC::Channel::Listener proxyementation. void OnMessageReceived(const IPC::Message& message); diff --git a/chrome/renderer/websharedworkerrepository_impl.cc b/chrome/renderer/websharedworkerrepository_impl.cc index 15aea07..24664b7 100644 --- a/chrome/renderer/websharedworkerrepository_impl.cc +++ b/chrome/renderer/websharedworkerrepository_impl.cc @@ -4,11 +4,11 @@ #include "chrome/renderer/websharedworkerrepository_impl.h" -WebKit::WebSharedWorker* WebSharedWorkerRepositoryImpl::lookup( - const WebKit::WebURL& url, - const WebKit::WebString& name, - DocumentID document) { - return NULL; +#include "chrome/renderer/websharedworker_proxy.h" + +void WebSharedWorkerRepositoryImpl::addSharedWorker( + WebKit::WebSharedWorker* worker, DocumentID document) { + // TODO(atwilson): Track shared worker creation here. } void WebSharedWorkerRepositoryImpl::documentDetached( diff --git a/chrome/renderer/websharedworkerrepository_impl.h b/chrome/renderer/websharedworkerrepository_impl.h index a0cda6d..4083202 100644 --- a/chrome/renderer/websharedworkerrepository_impl.h +++ b/chrome/renderer/websharedworkerrepository_impl.h @@ -12,12 +12,8 @@ namespace WebKit { } class WebSharedWorkerRepositoryImpl : public WebKit::WebSharedWorkerRepository { - virtual WebKit::WebSharedWorker* lookup(const WebKit::WebURL& url, - const WebKit::WebString& name, - DocumentID document); - + virtual void addSharedWorker(WebKit::WebSharedWorker*, DocumentID document); virtual void documentDetached(DocumentID document); - virtual bool hasSharedWorkers(DocumentID document); }; diff --git a/chrome/worker/webworkerclient_proxy.cc b/chrome/worker/webworkerclient_proxy.cc index baff23c..35b2a28 100644 --- a/chrome/worker/webworkerclient_proxy.cc +++ b/chrome/worker/webworkerclient_proxy.cc @@ -91,6 +91,11 @@ void WebWorkerClientProxy::reportPendingActivity(bool has_pending_activity) { route_id_, has_pending_activity)); } +void WebWorkerClientProxy::workerContextClosed() { + // TODO(atwilson): Notify WorkerProcessHost that the worker context is closing + // (needed for shared workers so we don't allow new connections). +} + void WebWorkerClientProxy::workerContextDestroyed() { Send(new WorkerHostMsg_WorkerContextDestroyed(route_id_)); // Tell the stub that the worker has shutdown - frees this object. diff --git a/chrome/worker/webworkerclient_proxy.h b/chrome/worker/webworkerclient_proxy.h index b422912..1f91b7e 100644 --- a/chrome/worker/webworkerclient_proxy.h +++ b/chrome/worker/webworkerclient_proxy.h @@ -46,6 +46,7 @@ class WebWorkerClientProxy : public WebKit::WebWorkerClient { const WebKit::WebString& source_url); virtual void confirmMessageFromWorkerObject(bool has_pending_activity); virtual void reportPendingActivity(bool has_pending_activity); + virtual void workerContextClosed(); virtual void workerContextDestroyed(); virtual WebKit::WebWorker* createWorker(WebKit::WebWorkerClient* client); diff --git a/webkit/api/WebKit.gyp b/webkit/api/WebKit.gyp index dbce149..0c8d4ca 100644 --- a/webkit/api/WebKit.gyp +++ b/webkit/api/WebKit.gyp @@ -282,6 +282,8 @@ 'src/WebURLError.cpp', 'src/WebViewImpl.cpp', 'src/WebViewImpl.h', + 'src/WebWorkerBase.cpp', + 'src/WebWorkerBase.h', 'src/WebWorkerClientImpl.cpp', 'src/WebWorkerClientImpl.h', 'src/WebWorkerImpl.cpp', diff --git a/webkit/api/public/WebCommonWorkerClient.h b/webkit/api/public/WebCommonWorkerClient.h index fd7e399..0726a43 100644 --- a/webkit/api/public/WebCommonWorkerClient.h +++ b/webkit/api/public/WebCommonWorkerClient.h @@ -57,6 +57,7 @@ namespace WebKit { int lineNumber, const WebString& sourceURL) = 0; + virtual void workerContextClosed() = 0; virtual void workerContextDestroyed() = 0; // Returns the notification presenter for this worker context. Pointer diff --git a/webkit/api/public/WebFrameClient.h b/webkit/api/public/WebFrameClient.h index a592c21..804f7b7 100644 --- a/webkit/api/public/WebFrameClient.h +++ b/webkit/api/public/WebFrameClient.h @@ -45,6 +45,7 @@ namespace WebKit { class WebNode; class WebPlugin; class WebSecurityOrigin; + class WebSharedWorker; class WebString; class WebURL; class WebURLRequest; @@ -67,6 +68,9 @@ namespace WebKit { virtual WebWorker* createWorker(WebFrame*, WebWorkerClient*) { return 0; } // May return null. + virtual WebSharedWorker* createSharedWorker(WebFrame*, const WebURL&, const WebString&, unsigned long long) { return 0; } + + // May return null. virtual WebMediaPlayer* createMediaPlayer(WebFrame*, WebMediaPlayerClient*) { return 0; } diff --git a/webkit/api/public/WebSharedWorker.h b/webkit/api/public/WebSharedWorker.h index a580882..5bdf6ae 100644 --- a/webkit/api/public/WebSharedWorker.h +++ b/webkit/api/public/WebSharedWorker.h @@ -33,8 +33,11 @@ #include "WebCommon.h" -namespace WebKit { +namespace WebCore { class ScriptExecutionContext; +} + +namespace WebKit { class WebString; class WebMessagePortChannel; class WebCommonWorkerClient; diff --git a/webkit/api/public/WebSharedWorkerRepository.h b/webkit/api/public/WebSharedWorkerRepository.h index b37b47a..508917c 100644 --- a/webkit/api/public/WebSharedWorkerRepository.h +++ b/webkit/api/public/WebSharedWorkerRepository.h @@ -43,9 +43,8 @@ namespace WebKit { // Unique identifier for the parent document of a worker (unique within a given process). typedef unsigned long long DocumentID; - // Connects the passed SharedWorker object with the specified worker thread. - // Caller is responsible for freeing the returned object. Returns null if a SharedWorker with that name already exists but with a different URL. - virtual WebSharedWorker* lookup(const WebURL&, const WebString&, DocumentID) = 0; + // Tracks a newly-created SharedWorker via the repository. + virtual void addSharedWorker(WebSharedWorker*, DocumentID) = 0; // Invoked when a document has been detached. DocumentID can be re-used after documentDetached() is invoked. virtual void documentDetached(DocumentID) = 0; diff --git a/webkit/api/src/SharedWorkerRepository.cpp b/webkit/api/src/SharedWorkerRepository.cpp index 32e8fd7..194e75a 100644 --- a/webkit/api/src/SharedWorkerRepository.cpp +++ b/webkit/api/src/SharedWorkerRepository.cpp @@ -40,6 +40,8 @@ #include "PlatformMessagePortChannel.h" #include "ScriptExecutionContext.h" #include "SharedWorker.h" +#include "WebFrameClient.h" +#include "WebFrameImpl.h" #include "WebKit.h" #include "WebKitClient.h" #include "WebMessagePortChannel.h" @@ -53,6 +55,7 @@ namespace WebCore { class Document; +using WebKit::WebFrameImpl;; using WebKit::WebMessagePortChannel; using WebKit::WebSharedWorker; using WebKit::WebSharedWorkerRepository; @@ -127,12 +130,16 @@ static WebSharedWorkerRepository::DocumentID getId(void* document) void SharedWorkerRepository::connect(PassRefPtr<SharedWorker> worker, PassOwnPtr<MessagePortChannel> port, const KURL& url, const String& name, ExceptionCode& ec) { - ScriptExecutionContext* context = worker->scriptExecutionContext(); + // This should not be callable unless there's a SharedWorkerRepository for + // this context (since isAvailable() should have returned null). + ASSERT(WebKit::webKitClient()->sharedWorkerRepository()); + // No nested workers (for now) - connect() should only be called from document context. - ASSERT(context->isDocument()); + ASSERT(worker->scriptExecutionContext()->isDocument()); + Document* document = static_cast<Document*>(worker->scriptExecutionContext()); + WebFrameImpl* webFrame = WebFrameImpl::fromFrame(document->frame()); OwnPtr<WebSharedWorker> webWorker; - ASSERT(WebKit::webKitClient()->sharedWorkerRepository()); - webWorker = WebKit::webKitClient()->sharedWorkerRepository()->lookup(url, name, getId(context)); + webWorker = webFrame->client()->createSharedWorker(webFrame, url, name, getId(document)); if (!webWorker) { // Existing worker does not match this url, so return an error back to the caller. diff --git a/webkit/api/src/WebSharedWorkerImpl.cpp b/webkit/api/src/WebSharedWorkerImpl.cpp index e5c9fc5..af76c2a 100644 --- a/webkit/api/src/WebSharedWorkerImpl.cpp +++ b/webkit/api/src/WebSharedWorkerImpl.cpp @@ -31,17 +31,93 @@ #include "config.h" #include "WebSharedWorkerImpl.h" +#include "GenericWorkerTask.h" +#include "KURL.h" +#include "MessageEvent.h" +#include "MessagePortChannel.h" +#include "PlatformMessagePortChannel.h" +#include "ScriptExecutionContext.h" +#include "SharedWorkerContext.h" +#include "SharedWorkerThread.h" + +#include "WebMessagePortChannel.h" +#include "WebString.h" +#include "WebURL.h" + using namespace WebCore; namespace WebKit { #if ENABLE(SHARED_WORKERS) -WebSharedWorker* WebSharedWorker::create(WebCommonWorkerClient* client) +WebSharedWorkerImpl::WebSharedWorkerImpl(WebCommonWorkerClient* client) + : m_client(client) +{ +} + +WebSharedWorkerImpl::~WebSharedWorkerImpl() +{ +} + +bool WebSharedWorkerImpl::isStarted() { - // FIXME: Return an instance of WebSharedWorkerImpl once the implementation is complete. + // Should not ever be called from the worker thread (this API is only called on WebSharedWorkerProxy on the renderer thread). ASSERT_NOT_REACHED(); - return NULL; + return workerThread(); +} + +void WebSharedWorkerImpl::connect(WebMessagePortChannel* webChannel) +{ + // Convert the WebMessagePortChanel to a WebCore::MessagePortChannel. + RefPtr<PlatformMessagePortChannel> platform_channel = + PlatformMessagePortChannel::create(webChannel); + webChannel->setClient(platform_channel.get()); + OwnPtr<MessagePortChannel> channel = + MessagePortChannel::create(platform_channel); + + workerThread()->runLoop().postTask( + createCallbackTask(&connectTask, this, channel.release())); +} + +void WebSharedWorkerImpl::connectTask(ScriptExecutionContext* context, WebSharedWorkerImpl* worker, PassOwnPtr<MessagePortChannel> channel) +{ + // Wrap the passed-in channel in a MessagePort, and send it off via a connect event. + RefPtr<MessagePort> port = MessagePort::create(*context); + port->entangle(channel.release()); + ASSERT(context->isWorkerContext()); + WorkerContext* workerContext = static_cast<WorkerContext*>(context); + ASSERT(workerContext->isSharedWorkerContext()); + workerContext->toSharedWorkerContext()->dispatchEvent(createConnectEvent(port)); +} + +void WebSharedWorkerImpl::startWorkerContext(const WebURL& url, const WebString& name, const WebString& userAgent, const WebString& sourceCode) +{ + initializeLoader(url); + setWorkerThread(SharedWorkerThread::create(name, url, userAgent, sourceCode, *this, *this)); + workerThread()->start(); +} + +void WebSharedWorkerImpl::terminateWorkerContext() +{ + stopWorkerThread(); +} + +void WebSharedWorkerImpl::clientDestroyed() +{ + m_client = 0; +} + +WebWorkerClient* WebSharedWorkerImpl::client() +{ + // We should never be asked for a WebWorkerClient (only dedicated workers have an associated WebWorkerClient). + // It should not be possible for SharedWorkerContext to generate an API call outside those supported by WebCommonWorkerClient. + ASSERT_NOT_REACHED(); + return 0; +} + +WebSharedWorker* WebSharedWorker::create(WebCommonWorkerClient* client) +{ + return new WebSharedWorkerImpl(client); } #endif // ENABLE(SHARED_WORKERS) diff --git a/webkit/api/src/WebSharedWorkerImpl.h b/webkit/api/src/WebSharedWorkerImpl.h index fad0f5a..7d38dbe 100644 --- a/webkit/api/src/WebSharedWorkerImpl.h +++ b/webkit/api/src/WebSharedWorkerImpl.h @@ -36,23 +36,16 @@ #if ENABLE(SHARED_WORKERS) #include "ScriptExecutionContext.h" -#include "WorkerLoaderProxy.h" -#include "WorkerObjectProxy.h" -#include <wtf/PassOwnPtr.h> -#include <wtf/RefPtr.h> -namespace WebCore { -class SharedWorkerThread; -} +#include "WebWorkerBase.h" namespace WebKit { -class WebView; // This class is used by the worker process code to talk to the WebCore::SharedWorker implementation. // It can't use it directly since it uses WebKit types, so this class converts the data types. // When the WebCore::SharedWorker object wants to call WebCore::WorkerReportingProxy, this class will // convert to Chrome data types first and then call the supplied WebCommonWorkerClient. -class WebSharedWorkerImpl : public WebCore::WorkerLoaderProxy { +class WebSharedWorkerImpl : public WebWorkerBase, public WebSharedWorker { public: explicit WebSharedWorkerImpl(WebCommonWorkerClient* client); @@ -60,15 +53,19 @@ public: virtual bool isStarted(); virtual void startWorkerContext(const WebURL&, const WebString& name, const WebString& userAgent, const WebString& sourceCode); virtual void connect(WebMessagePortChannel*); + virtual void terminateWorkerContext(); + virtual void clientDestroyed(); - WebCommonWorkerClient* client() { return m_client; } + // WebWorkerBase methods: + WebWorkerClient* client(); + WebCommonWorkerClient* commonClient() { return m_client; } private: virtual ~WebSharedWorkerImpl(); - WebCommonWorkerClient* m_client; + static void connectTask(WebCore::ScriptExecutionContext*, WebSharedWorkerImpl*, PassOwnPtr<WebCore::MessagePortChannel>); - RefPtr<WebCore::SharedWorkerThread> m_workerThread; + WebCommonWorkerClient* m_client; }; } // namespace WebKit diff --git a/webkit/api/src/WebWorkerBase.cpp b/webkit/api/src/WebWorkerBase.cpp new file mode 100644 index 0000000..3f19c4b --- /dev/null +++ b/webkit/api/src/WebWorkerBase.cpp @@ -0,0 +1,307 @@ +/* + * 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 "WorkerThread.h" +#include <wtf/MainThread.h> + +#include "PlatformMessagePortChannel.h" +#include "WebDataSourceImpl.h" +#include "WebFrameClient.h" +#include "WebFrameImpl.h" +#include "WebMessagePortChannel.h" +#include "WebWorkerClient.h" +#include "WebView.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/api/src/WebWorkerBase.h b/webkit/api/src/WebWorkerBase.h new file mode 100644 index 0000000..0217401 --- /dev/null +++ b/webkit/api/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/api/src/WebWorkerClientImpl.cpp b/webkit/api/src/WebWorkerClientImpl.cpp index 5e99b57..6be03a7 100644 --- a/webkit/api/src/WebWorkerClientImpl.cpp +++ b/webkit/api/src/WebWorkerClientImpl.cpp @@ -139,7 +139,7 @@ void WebWorkerClientImpl::startWorkerContext(const KURL& scriptURL, if (m_askedToTerminate) return; if (!isMainThread()) { - WebWorkerImpl::dispatchTaskToMainThread(createCallbackTask( + WebWorkerBase::dispatchTaskToMainThread(createCallbackTask( &startWorkerContextTask, this, scriptURL.string(), @@ -156,7 +156,7 @@ void WebWorkerClientImpl::terminateWorkerContext() return; m_askedToTerminate = true; if (!isMainThread()) { - WebWorkerImpl::dispatchTaskToMainThread(createCallbackTask(&terminateWorkerContextTask, this)); + WebWorkerBase::dispatchTaskToMainThread(createCallbackTask(&terminateWorkerContextTask, this)); return; } m_webWorker->terminateWorkerContext(); @@ -171,7 +171,7 @@ void WebWorkerClientImpl::postMessageToWorkerContext( return; ++m_unconfirmedMessageCount; if (!isMainThread()) { - WebWorkerImpl::dispatchTaskToMainThread(createCallbackTask(&postMessageToWorkerContextTask, + WebWorkerBase::dispatchTaskToMainThread(createCallbackTask(&postMessageToWorkerContextTask, this, message->toString(), channels)); @@ -201,7 +201,7 @@ void WebWorkerClientImpl::workerObjectDestroyed() } // 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. - WebWorkerImpl::dispatchTaskToMainThread(createCallbackTask(&workerObjectDestroyedTask, + WebWorkerBase::dispatchTaskToMainThread(createCallbackTask(&workerObjectDestroyedTask, this)); } @@ -302,6 +302,10 @@ void WebWorkerClientImpl::workerContextDestroyed() { } +void WebWorkerClientImpl::workerContextClosed() +{ +} + void WebWorkerClientImpl::startWorkerContextTask(ScriptExecutionContext* context, WebWorkerClientImpl* thisPtr, const String& scriptURL, diff --git a/webkit/api/src/WebWorkerClientImpl.h b/webkit/api/src/WebWorkerClientImpl.h index fe59651..63acebc 100644 --- a/webkit/api/src/WebWorkerClientImpl.h +++ b/webkit/api/src/WebWorkerClientImpl.h @@ -82,6 +82,7 @@ public: 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() diff --git a/webkit/api/src/WebWorkerImpl.cpp b/webkit/api/src/WebWorkerImpl.cpp index 77eb73c..744be30 100644 --- a/webkit/api/src/WebWorkerImpl.cpp +++ b/webkit/api/src/WebWorkerImpl.cpp @@ -42,18 +42,12 @@ #include "SecurityOrigin.h" #include "SerializedScriptValue.h" #include "SubstituteData.h" -#include <wtf/MainThread.h> #include <wtf/Threading.h> #include "PlatformMessagePortChannel.h" -#include "WebDataSourceImpl.h" -#include "WebFrameClient.h" -#include "WebFrameImpl.h" #include "WebMessagePortChannel.h" -#include "WebScreenInfo.h" #include "WebString.h" #include "WebURL.h" -#include "WebView.h" #include "WebWorkerClient.h" using namespace WebCore; @@ -62,64 +56,24 @@ 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 WebKit::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() - { - } -}; - WebWorker* WebWorker::create(WebWorkerClient* client) { return new WebWorkerImpl(client); } -// 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. -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(); - } -} WebWorkerImpl::WebWorkerImpl(WebWorkerClient* client) : m_client(client) - , m_webView(0) - , m_askedToTerminate(false) { - initializeWebKitStaticValues(); } WebWorkerImpl::~WebWorkerImpl() { - m_webView->close(); +} + +WebCommonWorkerClient* WebWorkerImpl::commonClient() +{ + return m_client; } void WebWorkerImpl::postMessageToWorkerContextTask(WebCore::ScriptExecutionContext* context, @@ -146,41 +100,17 @@ void WebWorkerImpl::startWorkerContext(const WebURL& scriptUrl, const WebString& userAgent, const WebString& sourceCode) { - // 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(scriptUrl, CString()); - webFrame->frame()->loader()->load(request, substData, false); - - // This document will be used as 'loading context' for the worker. - m_loadingDocument = webFrame->frame()->document(); - - m_workerThread = DedicatedWorkerThread::create(scriptUrl, userAgent, - sourceCode, *this, *this); + initializeLoader(scriptUrl); + setWorkerThread(DedicatedWorkerThread::create(scriptUrl, userAgent, + sourceCode, *this, *this)); // Worker initialization means a pending activity. reportPendingActivity(true); - m_workerThread->start(); + workerThread()->start(); } void WebWorkerImpl::terminateWorkerContext() { - if (m_askedToTerminate) - return; - m_askedToTerminate = true; - if (m_workerThread) - m_workerThread->stop(); + stopWorkerThread(); } void WebWorkerImpl::postMessageToWorkerContext(const WebString& message, @@ -197,7 +127,7 @@ void WebWorkerImpl::postMessageToWorkerContext(const WebString& message, } } - m_workerThread->runLoop().postTask( + workerThread()->runLoop().postTask( createCallbackTask(&postMessageToWorkerContextTask, this, String(message), channels.release())); } @@ -216,158 +146,6 @@ void WebWorkerImpl::clientDestroyed() m_client = 0; } -void WebWorkerImpl::dispatchTaskToMainThread(PassOwnPtr<ScriptExecutionContext::Task> task) -{ - return callOnMainThread(invokeTaskMethod, task.release()); -} - -void WebWorkerImpl::invokeTaskMethod(void* param) -{ - ScriptExecutionContext::Task* task = - static_cast<ScriptExecutionContext::Task*>(param); - task->performTask(0); - delete task; -} - -// WorkerObjectProxy ----------------------------------------------------------- - -void WebWorkerImpl::postMessageToWorkerObject(PassRefPtr<SerializedScriptValue> message, - PassOwnPtr<MessagePortChannelArray> channels) -{ - dispatchTaskToMainThread(createCallbackTask(&postMessageTask, this, - message->toString(), channels)); -} - -void WebWorkerImpl::postMessageTask(ScriptExecutionContext* context, - WebWorkerImpl* thisPtr, - String message, - PassOwnPtr<MessagePortChannelArray> channels) -{ - if (!thisPtr->m_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->m_client->postMessageToWorkerObject(message, webChannels); -} - -void WebWorkerImpl::postExceptionToWorkerObject(const String& errorMessage, - int lineNumber, - const String& sourceURL) -{ - dispatchTaskToMainThread(createCallbackTask(&postExceptionTask, this, - errorMessage, lineNumber, - sourceURL)); -} - -void WebWorkerImpl::postExceptionTask(ScriptExecutionContext* context, - WebWorkerImpl* thisPtr, - const String& errorMessage, - int lineNumber, const String& sourceURL) -{ - if (!thisPtr->m_client) - return; - - thisPtr->m_client->postExceptionToWorkerObject(errorMessage, - lineNumber, - sourceURL); -} - -void WebWorkerImpl::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 WebWorkerImpl::postConsoleMessageTask(ScriptExecutionContext* context, - WebWorkerImpl* thisPtr, - int destination, int source, - int type, int level, - const String& message, - int lineNumber, - const String& sourceURL) -{ - if (!thisPtr->m_client) - return; - thisPtr->m_client->postConsoleMessageToWorkerObject(destination, source, - type, level, message, - lineNumber, sourceURL); -} - -void WebWorkerImpl::confirmMessageFromWorkerObject(bool hasPendingActivity) -{ - dispatchTaskToMainThread(createCallbackTask(&confirmMessageTask, this, - hasPendingActivity)); -} - -void WebWorkerImpl::confirmMessageTask(ScriptExecutionContext* context, - WebWorkerImpl* thisPtr, - bool hasPendingActivity) -{ - if (!thisPtr->m_client) - return; - thisPtr->m_client->confirmMessageFromWorkerObject(hasPendingActivity); -} - -void WebWorkerImpl::reportPendingActivity(bool hasPendingActivity) -{ - dispatchTaskToMainThread(createCallbackTask(&reportPendingActivityTask, - this, hasPendingActivity)); -} - -void WebWorkerImpl::reportPendingActivityTask(ScriptExecutionContext* context, - WebWorkerImpl* thisPtr, - bool hasPendingActivity) -{ - if (!thisPtr->m_client) - return; - thisPtr->m_client->reportPendingActivity(hasPendingActivity); -} - -void WebWorkerImpl::workerContextDestroyed() -{ - dispatchTaskToMainThread(createCallbackTask(&workerContextDestroyedTask, - this)); -} - -// WorkerLoaderProxy ----------------------------------------------------------- - -void WebWorkerImpl::postTaskToLoader(PassOwnPtr<ScriptExecutionContext::Task> task) -{ - ASSERT(m_loadingDocument->isDocument()); - m_loadingDocument->postTask(task); -} - -void WebWorkerImpl::postTaskForModeToWorkerContext( - PassOwnPtr<ScriptExecutionContext::Task> task, const String& mode) -{ - m_workerThread->runLoop().postTaskForMode(task, mode); -} - -void WebWorkerImpl::workerContextDestroyedTask(ScriptExecutionContext* context, - WebWorkerImpl* thisPtr) -{ - if (thisPtr->m_client) - thisPtr->m_client->workerContextDestroyed(); - // The lifetime of this proxy is controlled by the worker context. - delete thisPtr; -} - - #else WebWorker* WebWorker::create(WebWorkerClient* client) diff --git a/webkit/api/src/WebWorkerImpl.h b/webkit/api/src/WebWorkerImpl.h index 49215593..bec96cd 100644 --- a/webkit/api/src/WebWorkerImpl.h +++ b/webkit/api/src/WebWorkerImpl.h @@ -36,14 +36,8 @@ #if ENABLE(WORKERS) #include "ScriptExecutionContext.h" -#include "WorkerLoaderProxy.h" -#include "WorkerObjectProxy.h" -#include <wtf/PassOwnPtr.h> -#include <wtf/RefPtr.h> -namespace WebCore { -class WorkerThread; -} +#include "WebWorkerBase.h" namespace WebKit { class WebView; @@ -53,30 +47,10 @@ class WebView; // 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 WebCore::WorkerObjectProxy - , public WebCore::WorkerLoaderProxy - , public WebWorker { +class WebWorkerImpl : public WebWorkerBase, public WebWorker { public: explicit WebWorkerImpl(WebWorkerClient* client); - // 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 workerContextDestroyed(); - - // WebCore::WorkerLoaderProxy methods: - virtual void postTaskToLoader(PassOwnPtr<WebCore::ScriptExecutionContext::Task>); - virtual void postTaskForModeToWorkerContext( - PassOwnPtr<WebCore::ScriptExecutionContext::Task>, const WebCore::String& mode); - // WebWorker methods: virtual void startWorkerContext(const WebURL&, const WebString&, const WebString&); virtual void terminateWorkerContext(); @@ -84,10 +58,9 @@ public: virtual void workerObjectDestroyed(); virtual void clientDestroyed(); - WebWorkerClient* client() {return m_client;} - - // Executes the given task on the main thread. - static void dispatchTaskToMainThread(PassOwnPtr<WebCore::ScriptExecutionContext::Task>); + // WebWorkerBase methods: + virtual WebWorkerClient* client() { return m_client; } + virtual WebCommonWorkerClient* commonClient(); private: virtual ~WebWorkerImpl(); @@ -99,51 +72,8 @@ private: const WebCore::String& message, PassOwnPtr<WebCore::MessagePortChannelArray> channels); - // 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, - WebWorkerImpl* thisPtr, - WebCore::String message, - PassOwnPtr<WebCore::MessagePortChannelArray> channels); - static void postExceptionTask( - WebCore::ScriptExecutionContext* context, - WebWorkerImpl* thisPtr, - const WebCore::String& message, - int lineNumber, - const WebCore::String& sourceURL); - static void postConsoleMessageTask( - WebCore::ScriptExecutionContext* context, - WebWorkerImpl* 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, - WebWorkerImpl* thisPtr, - bool hasPendingActivity); - static void reportPendingActivityTask( - WebCore::ScriptExecutionContext* context, - WebWorkerImpl* thisPtr, - bool hasPendingActivity); - static void workerContextDestroyedTask( - WebCore::ScriptExecutionContext* context, - WebWorkerImpl* thisPtr); - WebWorkerClient* m_client; - // '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 diff --git a/webkit/tools/test_shell/test_web_worker.h b/webkit/tools/test_shell/test_web_worker.h index 2aa1a2a..46595f2 100644 --- a/webkit/tools/test_shell/test_web_worker.h +++ b/webkit/tools/test_shell/test_web_worker.h @@ -66,6 +66,7 @@ class TestWebWorker : public WebKit::WebWorker, } virtual void confirmMessageFromWorkerObject(bool has_pending_activity) { } virtual void reportPendingActivity(bool has_pending_activity) { } + virtual void workerContextClosed() { } virtual void workerContextDestroyed() { Release(); // Releases the reference held for worker context object. } |