summaryrefslogtreecommitdiffstats
path: root/WebKit/chromium/src/WebWorkerBase.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'WebKit/chromium/src/WebWorkerBase.cpp')
-rw-r--r--WebKit/chromium/src/WebWorkerBase.cpp124
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);
}