2009-01-23 Dmitry Titov <dimich@chromium.org>
authorap@webkit.org <ap@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 23 Jan 2009 15:53:42 +0000 (15:53 +0000)
committerap@webkit.org <ap@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 23 Jan 2009 15:53:42 +0000 (15:53 +0000)
        Reviewed by Alexey Proskuryakov.

        https://bugs.webkit.org/show_bug.cgi?id=23374
        Add WorkerRunLoop to encapsulate message queue and timer heap.
        This is first half (timer heap is added as separate patch).

        * GNUmakefile.am: Added WorkerRunLoop.cpp to the build.
        * WebCore.vcproj/WebCore.vcproj: Same as above.
        * WebCore.xcodeproj/project.pbxproj: Same as above
        * dom/WorkerContext.cpp:
        (WebCore::WorkerContext::postTask):
        * dom/WorkerContext.h:
        * dom/WorkerMessagingProxy.cpp:
        (WebCore::WorkerMessagingProxy::postMessageToWorkerContext):
        (WebCore::WorkerMessagingProxy::workerThreadCreated):
        * dom/WorkerRunLoop.cpp: Added.
        (WebCore::WorkerRunLoop::run): Runs the loop until terminate() is called.
        (WebCore::WorkerRunLoop::terminate): Causes the loop to exit.
        (WebCore::WorkerRunLoop::postTask): Adds a task to the internal queue.
        * dom/WorkerRunLoop.h: Added.
        (WebCore::WorkerRunLoop::WorkerRunLoop):
        * dom/WorkerThread.cpp:
        (WebCore::WorkerThread::workerThread):
        (WebCore::WorkerThread::stop):
        * dom/WorkerThread.h:
        (WebCore::WorkerThread::runLoop):

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

WebCore/ChangeLog
WebCore/GNUmakefile.am
WebCore/WebCore.vcproj/WebCore.vcproj
WebCore/WebCore.xcodeproj/project.pbxproj
WebCore/dom/WorkerContext.cpp
WebCore/dom/WorkerContext.h
WebCore/dom/WorkerMessagingProxy.cpp
WebCore/dom/WorkerRunLoop.cpp [new file with mode: 0644]
WebCore/dom/WorkerRunLoop.h [new file with mode: 0644]
WebCore/dom/WorkerThread.cpp
WebCore/dom/WorkerThread.h

index 9d31fe63246d23a6c948f33b56fe368d3ae4f919..548b0b77ee4f9f04b9ba5f280d3007d40674ea0e 100644 (file)
@@ -1,3 +1,32 @@
+2009-01-23  Dmitry Titov  <dimich@chromium.org>
+
+        Reviewed by Alexey Proskuryakov.
+
+        https://bugs.webkit.org/show_bug.cgi?id=23374
+        Add WorkerRunLoop to encapsulate message queue and timer heap.
+        This is first half (timer heap is added as separate patch).
+
+        * GNUmakefile.am: Added WorkerRunLoop.cpp to the build.
+        * WebCore.vcproj/WebCore.vcproj: Same as above.
+        * WebCore.xcodeproj/project.pbxproj: Same as above
+        * dom/WorkerContext.cpp:
+        (WebCore::WorkerContext::postTask):
+        * dom/WorkerContext.h:
+        * dom/WorkerMessagingProxy.cpp:
+        (WebCore::WorkerMessagingProxy::postMessageToWorkerContext):
+        (WebCore::WorkerMessagingProxy::workerThreadCreated):
+        * dom/WorkerRunLoop.cpp: Added.
+        (WebCore::WorkerRunLoop::run): Runs the loop until terminate() is called.
+        (WebCore::WorkerRunLoop::terminate): Causes the loop to exit.
+        (WebCore::WorkerRunLoop::postTask): Adds a task to the internal queue.
+        * dom/WorkerRunLoop.h: Added.
+        (WebCore::WorkerRunLoop::WorkerRunLoop):
+        * dom/WorkerThread.cpp:
+        (WebCore::WorkerThread::workerThread):
+        (WebCore::WorkerThread::stop):
+        * dom/WorkerThread.h:
+        (WebCore::WorkerThread::runLoop):
+
 2009-01-23  Adam Treat  <adam.treat@torchmobile.com>
 
         Reviewed by Holger Hans Peter Freyther.
index cdf5a20999d9fa699453b99f09d2e694a976dd8d..8c079c853a7b2f06ca1568c04b5e14c865101524 100644 (file)
@@ -2188,6 +2188,8 @@ webcore_sources += \
        WebCore/dom/WorkerLocation.h \
        WebCore/dom/WorkerMessagingProxy.cpp \
        WebCore/dom/WorkerMessagingProxy.h \
+       WebCore/dom/WorkerRunLoop.cpp \
+       WebCore/dom/WorkerRunLoop.h \
        WebCore/dom/WorkerTask.cpp \
        WebCore/dom/WorkerTask.h \
        WebCore/dom/WorkerThread.cpp \
index aef2c0cb864c57a4bc853dead9806ce1e6ca9a31..118be206494a3d2b233a92a380744d12a937fda9 100644 (file)
                                RelativePath="..\dom\WorkerMessagingProxy.h"\r
                                >\r
                        </File>\r
+                       <File\r
+                               RelativePath="..\dom\WorkerRunLoop.cpp"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\dom\WorkerRunLoop.h"\r
+                               >\r
+                       </File>\r
                        <File\r
                                RelativePath="..\dom\WorkerTask.cpp"\r
                                >\r
index 0d60674f5660b4988bd4d91f460b598312f67af4..4205c2fb5d18830f95fe7d53f155d3601225e9ed 100644 (file)
                14EC268009CA07E000E1EEEC /* EventTargetNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 14EC267E09CA07E000E1EEEC /* EventTargetNode.cpp */; };
                14FFE31D0AE1963300136BF5 /* HTMLFrameElementBase.h in Headers */ = {isa = PBXBuildFile; fileRef = 14FFE31B0AE1963300136BF5 /* HTMLFrameElementBase.h */; settings = {ATTRIBUTES = (Private, ); }; };
                14FFE31E0AE1963300136BF5 /* HTMLFrameElementBase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 14FFE31C0AE1963300136BF5 /* HTMLFrameElementBase.cpp */; };
+               18A0537C0F26859C00A51705 /* WorkerRunLoop.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 18A0537A0F26859C00A51705 /* WorkerRunLoop.cpp */; };
+               18A0537D0F26859C00A51705 /* WorkerRunLoop.h in Headers */ = {isa = PBXBuildFile; fileRef = 18A0537B0F26859C00A51705 /* WorkerRunLoop.h */; };
                18E687870EDB793500A8E8B7 /* DOMTimer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 18E687850EDB793400A8E8B7 /* DOMTimer.cpp */; };
                18E687880EDB793500A8E8B7 /* DOMTimer.h in Headers */ = {isa = PBXBuildFile; fileRef = 18E687860EDB793500A8E8B7 /* DOMTimer.h */; };
                1A0D57360A5C77FE007EDD4C /* OverflowEvent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A0D57340A5C77FE007EDD4C /* OverflowEvent.cpp */; };
                14EC267E09CA07E000E1EEEC /* EventTargetNode.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = EventTargetNode.cpp; sourceTree = "<group>"; };
                14FFE31B0AE1963300136BF5 /* HTMLFrameElementBase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HTMLFrameElementBase.h; sourceTree = "<group>"; };
                14FFE31C0AE1963300136BF5 /* HTMLFrameElementBase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HTMLFrameElementBase.cpp; sourceTree = "<group>"; };
+               18A0537A0F26859C00A51705 /* WorkerRunLoop.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WorkerRunLoop.cpp; sourceTree = "<group>"; };
+               18A0537B0F26859C00A51705 /* WorkerRunLoop.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WorkerRunLoop.h; sourceTree = "<group>"; };
                18E687850EDB793400A8E8B7 /* DOMTimer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DOMTimer.cpp; sourceTree = "<group>"; };
                18E687860EDB793500A8E8B7 /* DOMTimer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DOMTimer.h; sourceTree = "<group>"; };
                1A0D57340A5C77FE007EDD4C /* OverflowEvent.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = OverflowEvent.cpp; sourceTree = "<group>"; };
                                E1C362BB0EAF29FB007410BC /* WorkerLocation.idl */,
                                E14799B30ECDE9D800292BF3 /* WorkerMessagingProxy.cpp */,
                                E14799A60ECDE3A400292BF3 /* WorkerMessagingProxy.h */,
+                               18A0537A0F26859C00A51705 /* WorkerRunLoop.cpp */,
+                               18A0537B0F26859C00A51705 /* WorkerRunLoop.h */,
                                E108224E0EC3156700E93953 /* WorkerTask.cpp */,
                                E108224A0EC3153A00E93953 /* WorkerTask.h */,
                                E1C2C4280EACE0E0007E61FB /* WorkerThread.cpp */,
                                1A569D230D7E2B82007C3983 /* runtime_object.h in Headers */,
                                1A569D250D7E2B82007C3983 /* runtime_root.h in Headers */,
                                93309E1E099E64920056E581 /* visible_units.h in Headers */,
+                               18A0537D0F26859C00A51705 /* WorkerRunLoop.h in Headers */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                E1C363060EAF2D07007410BC /* WorkerLocation.cpp in Sources */,
                                E14799B40ECDE9D800292BF3 /* WorkerMessagingProxy.cpp in Sources */,
                                E1271A140EEEC80400F61213 /* WorkerNavigator.cpp in Sources */,
+                               18A0537C0F26859C00A51705 /* WorkerRunLoop.cpp in Sources */,
                                E1A643FD0EC097A000779668 /* WorkerScriptController.cpp in Sources */,
                                E108224F0EC3156700E93953 /* WorkerTask.cpp in Sources */,
                                E1C2C4290EACE0E0007E61FB /* WorkerThread.cpp in Sources */,
index 8620881a65e8c10174de6574a950a0377559a8c7..fe4643efd833caa7e0bef5e456d774d9db2e1dbb 100644 (file)
@@ -210,7 +210,7 @@ private:
 
 void WorkerContext::postTask(PassRefPtr<Task> task)
 {
-    thread()->messageQueue().append(ScriptExecutionContextTaskWorkerTask::create(task));
+    thread()->runLoop().postTask(ScriptExecutionContextTaskWorkerTask::create(task));
 }
 
 void WorkerContext::postTaskToParentContext(PassRefPtr<Task> task)
index 4d4b29979e4ac9f9933b3dbe5b56f626f345c0d2..2e443d9a42f1f48264c9f08a3d51e4f153ea870f 100644 (file)
@@ -43,7 +43,6 @@ namespace WebCore {
 
     class WorkerLocation;
     class WorkerNavigator;
-    class WorkerTask;
     class WorkerThread;
 
     class WorkerContext : public RefCounted<WorkerContext>, public ScriptExecutionContext, public EventTarget {
index 721bf13caf6246ad01e3f8f1412ea26b20bca45d..b0d145ef6178c190a1f8e8da44186a755efb8741 100644 (file)
@@ -218,7 +218,7 @@ void WorkerMessagingProxy::postMessageToWorkerContext(const String& message)
 
     if (m_workerThread) {
         ++m_unconfirmedMessageCount;
-        m_workerThread->messageQueue().append(MessageWorkerContextTask::create(message));
+        m_workerThread->runLoop().postTask(MessageWorkerContextTask::create(message));
     } else
         m_queuedEarlyTasks.append(MessageWorkerContextTask::create(message));
 }
@@ -246,7 +246,7 @@ void WorkerMessagingProxy::workerThreadCreated(PassRefPtr<WorkerThread> workerTh
         m_unconfirmedMessageCount = taskCount + 1; // Worker initialization counts as a pending message.
 
         for (unsigned i = 0; i < taskCount; ++i)
-            m_workerThread->messageQueue().append(m_queuedEarlyTasks[i]);
+            m_workerThread->runLoop().postTask(m_queuedEarlyTasks[i]);
         m_queuedEarlyTasks.clear();
     }
 }
diff --git a/WebCore/dom/WorkerRunLoop.cpp b/WebCore/dom/WorkerRunLoop.cpp
new file mode 100644 (file)
index 0000000..98c2e8d
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ * 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"
+
+#if ENABLE(WORKERS)
+
+#include "WorkerRunLoop.h"
+#include "WorkerContext.h"
+#include "WorkerTask.h"
+#include "WorkerThread.h"
+
+namespace WebCore {
+
+void WorkerRunLoop::run(WorkerContext* context)
+{
+    ASSERT(context);
+    ASSERT(context->thread());
+    ASSERT(context->thread()->threadID() == currentThread());
+    
+    while (true) {
+        RefPtr<WorkerTask> task;
+        if (!m_messageQueue.waitForMessage(task))
+            break;
+
+        task->performTask(context);
+    }
+}
+
+void WorkerRunLoop::terminate()
+{
+    m_messageQueue.kill();
+}
+
+void WorkerRunLoop::postTask(PassRefPtr<WorkerTask> task)
+{
+    m_messageQueue.append(task);
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(WORKERS)
diff --git a/WebCore/dom/WorkerRunLoop.h b/WebCore/dom/WorkerRunLoop.h
new file mode 100644 (file)
index 0000000..03a746b
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * 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 WorkerRunLoop_h
+#define WorkerRunLoop_h
+
+#if ENABLE(WORKERS)
+
+#include "WorkerTask.h"
+#include <wtf/MessageQueue.h>
+#include <wtf/PassRefPtr.h>
+
+namespace WebCore {
+
+    class WorkerContext;
+
+    class WorkerRunLoop {
+    public:
+        WorkerRunLoop() {}
+        
+        // Blocking call. Waits for tasks and timers, invokes the callbacks.
+        void run(WorkerContext*);
+        
+        void terminate();
+        bool terminated() { return m_messageQueue.killed(); }
+
+        void postTask(PassRefPtr<WorkerTask>);
+        
+    private:
+        MessageQueue<RefPtr<WorkerTask> > m_messageQueue;
+    };
+
+} // namespace WebCore
+
+#endif // ENABLE(WORKERS)
+
+#endif // WorkerRunLoop_h
index b50f131c88b8770763cb75133f6902a8cc09f0c0..a762e0bf39b1d3e661e3b0b5ef8723947cbc63cb 100644 (file)
@@ -103,7 +103,7 @@ void* WorkerThread::workerThread()
     {
         MutexLocker lock(m_threadCreationMutex);
         m_workerContext = WorkerContext::create(m_startupData->m_scriptURL, m_startupData->m_userAgent, this);
-        if (m_messageQueue.killed()) {
+        if (m_runLoop.terminated()) {
             // The worker was terminated before the thread had a chance to run. Since the context didn't exist yet, 
             // forbidExecution() couldn't be called from stop().
            m_workerContext->script()->forbidExecution();
@@ -119,13 +119,8 @@ void* WorkerThread::workerThread()
 
     m_messagingProxy->confirmWorkerThreadMessage(m_workerContext->hasPendingActivity()); // This wasn't really a message, but it counts as one for GC.
 
-    while (true) {
-        RefPtr<WorkerTask> task;
-        if (!m_messageQueue.waitForMessage(task))
-            break;
-
-        task->performTask(m_workerContext.get());
-    }
+    // Blocks until terminated.
+    m_runLoop.run(m_workerContext.get());
 
     ThreadIdentifier threadID = m_threadID;
 
@@ -151,7 +146,7 @@ void WorkerThread::stop()
         m_workerContext->script()->forbidExecution();
 
     // FIXME: Rudely killing the thread won't work when we allow nested workers, because they will try to post notifications of their destruction.
-    m_messageQueue.kill();
+    m_runLoop.terminate();
 }
 
 } // namespace WebCore
index ca3e96589f30e058832f9dba06cc02a7d006bea4..504db8167118ed13959a3854b9e8a23ce3fa0872 100644 (file)
@@ -29,7 +29,7 @@
 
 #if ENABLE(WORKERS)
 
-#include <wtf/MessageQueue.h>
+#include <WorkerRunLoop.h>
 #include <wtf/OwnPtr.h>
 #include <wtf/PassRefPtr.h>
 #include <wtf/RefCounted.h>
@@ -52,8 +52,7 @@ namespace WebCore {
         void stop();
 
         ThreadIdentifier threadID() const { return m_threadID; }
-        MessageQueue<RefPtr<WorkerTask> >& messageQueue() { return m_messageQueue; }
-
+        WorkerRunLoop& runLoop() { return m_runLoop; }
         WorkerMessagingProxy* messagingProxy() const { return m_messagingProxy; }
 
     private:
@@ -63,12 +62,12 @@ namespace WebCore {
         void* workerThread();
 
         ThreadIdentifier m_threadID;
+        WorkerRunLoop m_runLoop;
         WorkerMessagingProxy* m_messagingProxy;
 
         RefPtr<WorkerContext> m_workerContext;
         Mutex m_threadCreationMutex;
 
-        MessageQueue<RefPtr<WorkerTask> > m_messageQueue;
         OwnPtr<WorkerThreadStartupData> m_startupData;
     };