2009-02-25 David Levin <levin@chromium.org>
authorlevin@chromium.org <levin@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 25 Feb 2009 18:06:35 +0000 (18:06 +0000)
committerlevin@chromium.org <levin@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 25 Feb 2009 18:06:35 +0000 (18:06 +0000)
        Reviewed by Alexey Proskuryakov.

        Bug 23688: ThreadableLoader needs a sync implementation for Workers.
        <https://bugs.webkit.org/show_bug.cgi?id=23688>

        No observable change in behavior, so no test.

        * loader/ThreadableLoader.cpp:
        (WebCore::ThreadableLoader::loadResourceSynchronously):
        * loader/ThreadableLoaderClientWrapper.h:
        (WebCore::ThreadableLoaderClientWrapper::clearClient):
        (WebCore::ThreadableLoaderClientWrapper::done):
        (WebCore::ThreadableLoaderClientWrapper::didFinishLoading):
        (WebCore::ThreadableLoaderClientWrapper::didFail):
        (WebCore::ThreadableLoaderClientWrapper::didFailRedirectCheck):
        (WebCore::ThreadableLoaderClientWrapper::ThreadableLoaderClientWrapper):
        Expose whether the loader is done (based on what callbacks were done).

        * loader/WorkerThreadableLoader.cpp:
        (WebCore::WorkerThreadableLoader::WorkerThreadableLoader):
        (WebCore::WorkerThreadableLoader::loadResourceSynchronously):
        Each loader is given its own mode so that only its callbacks get through the run loop.

        The xhr spec says that the readystatechange events are synchronous, so in the case of a
        nested sync xhr no readystatechange events should be fired for the outer xhr.

        (WebCore::WorkerThreadableLoader::MainThreadBridge::MainThreadBridge):

        * loader/WorkerThreadableLoader.h:
        (WebCore::WorkerThreadableLoader::create):
        (WebCore::WorkerThreadableLoader::done):

        * workers/WorkerRunLoop.cpp:
        (WebCore::WorkerRunLoop::WorkerRunLoop):
        * workers/WorkerRunLoop.h:
        (WebCore::WorkerRunLoop::createUniqueId):
        Simple method to create a uniqueId on demand with respect to the run loop.

        * workers/WorkerThread.h:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@41216 268f45cc-cd09-0410-ab3c-d52691b4dbfc

WebCore/ChangeLog
WebCore/loader/ThreadableLoader.cpp
WebCore/loader/ThreadableLoaderClientWrapper.h
WebCore/loader/WorkerThreadableLoader.cpp
WebCore/loader/WorkerThreadableLoader.h
WebCore/workers/WorkerRunLoop.cpp
WebCore/workers/WorkerRunLoop.h
WebCore/workers/WorkerThread.h

index e9fad2a..992c8fc 100644 (file)
@@ -2,6 +2,48 @@
 
         Reviewed by Alexey Proskuryakov.
 
+        Bug 23688: ThreadableLoader needs a sync implementation for Workers.
+        <https://bugs.webkit.org/show_bug.cgi?id=23688>
+
+        No observable change in behavior, so no test.
+
+        * loader/ThreadableLoader.cpp:
+        (WebCore::ThreadableLoader::loadResourceSynchronously):
+        * loader/ThreadableLoaderClientWrapper.h:
+        (WebCore::ThreadableLoaderClientWrapper::clearClient):
+        (WebCore::ThreadableLoaderClientWrapper::done):
+        (WebCore::ThreadableLoaderClientWrapper::didFinishLoading):
+        (WebCore::ThreadableLoaderClientWrapper::didFail):
+        (WebCore::ThreadableLoaderClientWrapper::didFailRedirectCheck):
+        (WebCore::ThreadableLoaderClientWrapper::ThreadableLoaderClientWrapper):
+        Expose whether the loader is done (based on what callbacks were done).
+
+        * loader/WorkerThreadableLoader.cpp:
+        (WebCore::WorkerThreadableLoader::WorkerThreadableLoader):
+        (WebCore::WorkerThreadableLoader::loadResourceSynchronously):
+        Each loader is given its own mode so that only its callbacks get through the run loop.
+
+        The xhr spec says that the readystatechange events are synchronous, so in the case of a
+        nested sync xhr no readystatechange events should be fired for the outer xhr.
+
+        (WebCore::WorkerThreadableLoader::MainThreadBridge::MainThreadBridge):
+
+        * loader/WorkerThreadableLoader.h:
+        (WebCore::WorkerThreadableLoader::create):
+        (WebCore::WorkerThreadableLoader::done):
+
+        * workers/WorkerRunLoop.cpp:
+        (WebCore::WorkerRunLoop::WorkerRunLoop):
+        * workers/WorkerRunLoop.h:
+        (WebCore::WorkerRunLoop::createUniqueId):
+        Simple method to create a uniqueId on demand with respect to the run loop.
+
+        * workers/WorkerThread.h:
+
+2009-02-25  David Levin  <levin@chromium.org>
+
+        Reviewed by Alexey Proskuryakov.
+
         Bug 24089: ThreadableLoader::loadResourceSynchronously should do callbacks like the async code.
         <https://bugs.webkit.org/show_bug.cgi?id=24089>
 
index 2cdca7b..1b2cc88 100644 (file)
@@ -57,6 +57,14 @@ PassRefPtr<ThreadableLoader> ThreadableLoader::create(ScriptExecutionContext* co
 void ThreadableLoader::loadResourceSynchronously(ScriptExecutionContext* context, const ResourceRequest& request, ThreadableLoaderClient& client)
 {
     ASSERT(context);
+
+#if ENABLE(WORKERS)
+    if (context->isWorkerContext()) {
+        WorkerThreadableLoader::loadResourceSynchronously(static_cast<WorkerContext*>(context), request, client);
+        return;
+    }
+#endif // ENABLE(WORKERS)
+
     ASSERT(context->isDocument());
     DocumentThreadableLoader::loadResourceSynchronously(static_cast<Document*>(context), request, client);
 }
index 4c6163f..d3c1a9f 100644 (file)
@@ -47,9 +47,15 @@ namespace WebCore {
 
         void clearClient()
         {
+            m_done = true;
             m_client = 0;
         }
 
+        bool done() const
+        {
+            return m_done;
+        }
+
         void didSendData(unsigned long long bytesSent, unsigned long long totalBytesToBeSent)
         {
             if (m_client)
@@ -70,18 +76,21 @@ namespace WebCore {
 
         void didFinishLoading(unsigned long identifier)
         {
+            m_done = true;
             if (m_client)
                 m_client->didFinishLoading(identifier);
         }
 
         void didFail(const ResourceError& error)
         {
+            m_done = true;
             if (m_client)
                 m_client->didFail(error);
         }
 
         void didFailRedirectCheck()
         {
+            m_done = true;
             if (m_client)
                 m_client->didFailRedirectCheck();
         }
@@ -95,10 +104,12 @@ namespace WebCore {
     protected:
         ThreadableLoaderClientWrapper(ThreadableLoaderClient* client)
             : m_client(client)
+            , m_done(false)
         {
         }
 
         ThreadableLoaderClient* m_client;
+        bool m_done;
     };
 
 } // namespace WebCore
index d801c2c..2fa3203 100644 (file)
@@ -51,11 +51,15 @@ using namespace std;
 
 namespace WebCore {
 
+static const char loadResourceSynchronouslyMode[] = "loadResourceSynchronouslyMode";
+
 // FIXME: The assumption that we can upcast worker object proxy to WorkerMessagingProxy will not be true in multi-process implementation.
 WorkerThreadableLoader::WorkerThreadableLoader(WorkerContext* workerContext, ThreadableLoaderClient* client, const String& taskMode, const ResourceRequest& request, LoadCallbacks callbacksSetting,
                                                ContentSniff contentSniff)
     : m_workerContext(workerContext)
-    , m_bridge(*(new MainThreadBridge(client, *(static_cast<WorkerMessagingProxy*>(m_workerContext->thread()->workerObjectProxy())), taskMode, request, callbacksSetting, contentSniff)))
+    , m_workerClientWrapper(ThreadableLoaderClientWrapper::create(client))
+    , m_bridge(*(new MainThreadBridge(m_workerClientWrapper, *(static_cast<WorkerMessagingProxy*>(m_workerContext->thread()->workerObjectProxy())), taskMode, request, callbacksSetting,
+                                      contentSniff)))
 {
 }
 
@@ -64,18 +68,32 @@ WorkerThreadableLoader::~WorkerThreadableLoader()
     m_bridge.destroy();
 }
 
+void WorkerThreadableLoader::loadResourceSynchronously(WorkerContext* workerContext, const ResourceRequest& request, ThreadableLoaderClient& client)
+{
+    WorkerRunLoop& runLoop = workerContext->thread()->runLoop();
+
+    // Create a unique mode just for this synchronous resource load.
+    String mode = loadResourceSynchronouslyMode;
+    mode.append(String::number(runLoop.createUniqueId()));
+
+    ContentSniff contentSniff = request.url().isLocalFile() ? SniffContent : DoNotSniffContent;
+    RefPtr<WorkerThreadableLoader> loader = WorkerThreadableLoader::create(workerContext, &client, mode, request, DoNotSendLoadCallbacks, contentSniff);
+    while (!loader->done())
+        runLoop.runInMode(workerContext, mode);
+}
+
 void WorkerThreadableLoader::cancel()
 {
     m_bridge.cancel();
 }
 
-WorkerThreadableLoader::MainThreadBridge::MainThreadBridge(ThreadableLoaderClient* workerClient, WorkerMessagingProxy& messagingProxy, const String& taskMode, const ResourceRequest& request,
-                                                           LoadCallbacks callbacksSetting, ContentSniff contentSniff)
-    : m_workerClientWrapper(ThreadableLoaderClientWrapper::create(workerClient))
+WorkerThreadableLoader::MainThreadBridge::MainThreadBridge(PassRefPtr<ThreadableLoaderClientWrapper> workerClientWrapper, WorkerMessagingProxy& messagingProxy, const String& taskMode,
+                                                           const ResourceRequest& request, LoadCallbacks callbacksSetting, ContentSniff contentSniff)
+    : m_workerClientWrapper(workerClientWrapper)
     , m_messagingProxy(messagingProxy)
     , m_taskMode(taskMode.copy())
 {
-    ASSERT(workerClient);
+    ASSERT(m_workerClientWrapper.get());
     m_messagingProxy.postTaskToWorkerObject(createCallbackTask(&MainThreadBridge::mainThreadCreateLoader, this, request, callbacksSetting, contentSniff));
 }
 
index f997e10..cd7c51d 100644 (file)
@@ -55,15 +55,18 @@ namespace WebCore {
 
     class WorkerThreadableLoader : public RefCounted<WorkerThreadableLoader>, public ThreadableLoader {
     public:
-        static PassRefPtr<WorkerThreadableLoader> create(WorkerContext* worker, ThreadableLoaderClient* client, const String& taskMode, const ResourceRequest& request, LoadCallbacks callbacksSetting, ContentSniff contentSniff)
+        static void loadResourceSynchronously(WorkerContext*, const ResourceRequest&, ThreadableLoaderClient&);
+        static PassRefPtr<WorkerThreadableLoader> create(WorkerContext* workerContext, ThreadableLoaderClient* client, const String& taskMode, const ResourceRequest& request, LoadCallbacks callbacksSetting, ContentSniff contentSniff)
         {
-            return adoptRef(new WorkerThreadableLoader(worker, client, taskMode, request, callbacksSetting, contentSniff));
+            return adoptRef(new WorkerThreadableLoader(workerContext, client, taskMode, request, callbacksSetting, contentSniff));
         }
 
         ~WorkerThreadableLoader();
 
         virtual void cancel();
 
+        bool done() const { return m_workerClientWrapper->done(); }
+
         using RefCounted<WorkerThreadableLoader>::ref;
         using RefCounted<WorkerThreadableLoader>::deref;
 
@@ -94,7 +97,7 @@ namespace WebCore {
         class MainThreadBridge : ThreadableLoaderClient {
         public:
             // All executed on the worker context's thread.
-            MainThreadBridge(ThreadableLoaderClient*, WorkerMessagingProxy&, const String& taskMode, const ResourceRequest&, LoadCallbacks, ContentSniff);
+            MainThreadBridge(PassRefPtr<ThreadableLoaderClientWrapper>, WorkerMessagingProxy&, const String& taskMode, const ResourceRequest&, LoadCallbacks, ContentSniff);
             void cancel();
             void destroy();
 
@@ -133,6 +136,7 @@ namespace WebCore {
         WorkerThreadableLoader(WorkerContext*, ThreadableLoaderClient*, const String& taskMode, const ResourceRequest&, LoadCallbacks, ContentSniff);
 
         RefPtr<WorkerContext> m_workerContext;
+        RefPtr<ThreadableLoaderClientWrapper> m_workerClientWrapper;
         MainThreadBridge& m_bridge;
     };
 
index 65877f7..1e5e510 100644 (file)
@@ -111,6 +111,7 @@ private:
 WorkerRunLoop::WorkerRunLoop()
     : m_sharedTimer(new WorkerSharedTimer)
     , m_nestedCount(0)
+    , m_uniqueId(0)
 {
 }
 
index 4d1eaa3..5f74f01 100644 (file)
@@ -61,6 +61,8 @@ namespace WebCore {
         void postTask(PassRefPtr<ScriptExecutionContext::Task>);
         void postTaskForMode(PassRefPtr<ScriptExecutionContext::Task>, const String& mode);
 
+        unsigned long createUniqueId() { return ++m_uniqueId; }
+
         static String defaultMode();
         class Task;
     private:
@@ -70,6 +72,7 @@ namespace WebCore {
         MessageQueue<RefPtr<Task> > m_messageQueue;
         OwnPtr<WorkerSharedTimer> m_sharedTimer;
         int m_nestedCount;
+        unsigned long m_uniqueId;
     };
 
 } // namespace WebCore
index b1ef5f5..f1a8a52 100644 (file)
@@ -29,7 +29,7 @@
 
 #if ENABLE(WORKERS)
 
-#include <WorkerRunLoop.h>
+#include "WorkerRunLoop.h"
 #include <wtf/OwnPtr.h>
 #include <wtf/PassRefPtr.h>
 #include <wtf/RefCounted.h>