diff options
Diffstat (limited to 'WebKit/chromium/src/WebWorkerBase.cpp')
| -rw-r--r-- | WebKit/chromium/src/WebWorkerBase.cpp | 124 |
1 files changed, 100 insertions, 24 deletions
diff --git a/WebKit/chromium/src/WebWorkerBase.cpp b/WebKit/chromium/src/WebWorkerBase.cpp index 40019e8..42f41d2 100644 --- a/WebKit/chromium/src/WebWorkerBase.cpp +++ b/WebKit/chromium/src/WebWorkerBase.cpp @@ -31,7 +31,8 @@ #include "config.h" #include "WebWorkerBase.h" -#include "GenericWorkerTask.h" +#include "CrossThreadTask.h" +#include "DatabaseTask.h" #include "MessagePortChannel.h" #include "PlatformMessagePortChannel.h" @@ -39,9 +40,12 @@ #include "WebFrameClient.h" #include "WebFrameImpl.h" #include "WebMessagePortChannel.h" +#include "WebRuntimeFeatures.h" +#include "WebSettings.h" #include "WebView.h" #include "WebWorkerClient.h" +#include "WorkerScriptController.h" #include "WorkerThread.h" #include <wtf/MainThread.h> @@ -51,29 +55,66 @@ 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 { +static const char allowDatabaseMode[] = "allowDatabaseMode"; + +namespace { + +// This class is used to route the result of the WebWorkerBase::allowDatabase +// call back to the worker context. +class AllowDatabaseMainThreadBridge : public ThreadSafeShared<AllowDatabaseMainThreadBridge> { 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 PassRefPtr<AllowDatabaseMainThreadBridge> create(WebWorkerBase* worker, const WTF::String& mode, WebCommonWorkerClient* commonClient, WebFrame* frame, const WTF::String& name, const WTF::String& displayName, unsigned long estimatedSize) + { + return adoptRef(new AllowDatabaseMainThreadBridge(worker, mode, commonClient, frame, name, displayName, estimatedSize)); + } + + // These methods are invoked on the worker context. + void cancel() + { + MutexLocker locker(m_mutex); + m_worker = 0; + } + + bool result() { - static_cast<WebDataSourceImpl*>(ds)->setDeferMainResourceDataLoad(false); + return m_result; } - // Lazy allocate and leak this instance. - static WorkerWebFrameClient* sharedInstance() + // This method is invoked on the main thread. + void signalCompleted(bool result) { - static WorkerWebFrameClient client; - return &client; + MutexLocker locker(m_mutex); + if (m_worker) + m_worker->postTaskForModeToWorkerContext(createCallbackTask(&didComplete, this, result), m_mode); } private: - WorkerWebFrameClient() + AllowDatabaseMainThreadBridge(WebWorkerBase* worker, const WTF::String& mode, WebCommonWorkerClient* commonClient, WebFrame* frame, const WTF::String& name, const WTF::String& displayName, unsigned long estimatedSize) + : m_worker(worker) + , m_mode(mode) { + worker->dispatchTaskToMainThread(createCallbackTask(&allowDatabaseTask, commonClient, frame, String(name), String(displayName), estimatedSize, this)); } + + static void allowDatabaseTask(WebCore::ScriptExecutionContext* context, WebCommonWorkerClient* commonClient, WebFrame* frame, const WTF::String name, const WTF::String displayName, unsigned long estimatedSize, PassRefPtr<AllowDatabaseMainThreadBridge> bridge) + { + if (!commonClient) + bridge->signalCompleted(false); + else + bridge->signalCompleted(commonClient->allowDatabase(frame, name, displayName, estimatedSize)); + } + + static void didComplete(WebCore::ScriptExecutionContext* context, PassRefPtr<AllowDatabaseMainThreadBridge> bridge, bool result) + { + bridge->m_result = result; + } + + bool m_result; + Mutex m_mutex; + WebWorkerBase* m_worker; + WTF::String m_mode; }; +} // 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 @@ -103,6 +144,9 @@ WebWorkerBase::WebWorkerBase() WebWorkerBase::~WebWorkerBase() { ASSERT(m_webView); + WebFrameImpl* webFrame = static_cast<WebFrameImpl*>(m_webView->mainFrame()); + if (webFrame) + webFrame->setClient(0); m_webView->close(); } @@ -121,8 +165,9 @@ void WebWorkerBase::initializeLoader(const WebURL& url) // 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()); + m_webView = WebView::create(0, 0); + m_webView->settings()->setOfflineWebApplicationCacheEnabled(WebRuntimeFeatures::isApplicationCacheEnabled()); + m_webView->initializeMainFrame(this); WebFrameImpl* webFrame = static_cast<WebFrameImpl*>(m_webView->mainFrame()); @@ -140,7 +185,7 @@ void WebWorkerBase::initializeLoader(const WebURL& url) void WebWorkerBase::dispatchTaskToMainThread(PassOwnPtr<ScriptExecutionContext::Task> task) { - return callOnMainThread(invokeTaskMethod, task.release()); + callOnMainThread(invokeTaskMethod, task.leakPtr()); } void WebWorkerBase::invokeTaskMethod(void* param) @@ -151,6 +196,41 @@ void WebWorkerBase::invokeTaskMethod(void* param) delete task; } +void WebWorkerBase::didCreateDataSource(WebFrame*, WebDataSource* ds) +{ + // Tell the loader to load the data into the 'shadow page' synchronously, + // so we can grab the resulting Document right after load. + static_cast<WebDataSourceImpl*>(ds)->setDeferMainResourceDataLoad(false); +} + +WebApplicationCacheHost* WebWorkerBase::createApplicationCacheHost(WebFrame*, WebApplicationCacheHostClient* appcacheHostClient) +{ + if (commonClient()) + return commonClient()->createApplicationCacheHost(appcacheHostClient); + return 0; +} + +bool WebWorkerBase::allowDatabase(WebFrame*, const WebString& name, const WebString& displayName, unsigned long estimatedSize) +{ + WorkerRunLoop& runLoop = m_workerThread->runLoop(); + WorkerScriptController* controller = WorkerScriptController::controllerForContext(); + WorkerContext* workerContext = controller->workerContext(); + + // Create a unique mode just for this synchronous call. + String mode = allowDatabaseMode; + mode.append(String::number(runLoop.createUniqueId())); + + RefPtr<AllowDatabaseMainThreadBridge> bridge = AllowDatabaseMainThreadBridge::create(this, mode, commonClient(), m_webView->mainFrame(), String(name), String(displayName), estimatedSize); + + // Either the bridge returns, or the queue gets terminated. + if (runLoop.runInMode(workerContext, mode) == MessageQueueTerminated) { + bridge->cancel(); + return false; + } + + return bridge->result(); +} + // WorkerObjectProxy ----------------------------------------------------------- void WebWorkerBase::postMessageToWorkerObject(PassRefPtr<SerializedScriptValue> message, @@ -199,8 +279,7 @@ void WebWorkerBase::postExceptionTask(ScriptExecutionContext* context, sourceURL); } -void WebWorkerBase::postConsoleMessageToWorkerObject(MessageDestination destination, - MessageSource source, +void WebWorkerBase::postConsoleMessageToWorkerObject(MessageSource source, MessageType type, MessageLevel level, const String& message, @@ -208,16 +287,13 @@ void WebWorkerBase::postConsoleMessageToWorkerObject(MessageDestination destinat const String& sourceURL) { dispatchTaskToMainThread(createCallbackTask(&postConsoleMessageTask, this, - static_cast<int>(destination), - static_cast<int>(source), - static_cast<int>(type), - static_cast<int>(level), + source, type, level, message, lineNumber, sourceURL)); } void WebWorkerBase::postConsoleMessageTask(ScriptExecutionContext* context, WebWorkerBase* thisPtr, - int destination, int source, + int source, int type, int level, const String& message, int lineNumber, @@ -225,7 +301,7 @@ void WebWorkerBase::postConsoleMessageTask(ScriptExecutionContext* context, { if (!thisPtr->commonClient()) return; - thisPtr->commonClient()->postConsoleMessageToWorkerObject(destination, source, + thisPtr->commonClient()->postConsoleMessageToWorkerObject(source, type, level, message, lineNumber, sourceURL); } |
