Title: [141497] trunk/Source/WebKit2
Revision
141497
Author
[email protected]
Date
2013-01-31 15:43:21 -0800 (Thu, 31 Jan 2013)

Log Message

WorkQueue should be a ref-counted class
https://bugs.webkit.org/show_bug.cgi?id=108544

Reviewed by Sam Weinig.

Make WorkQueue a ref-counted class that's implicitly ref()'d when dispatching a function to it, and then
implicitly deref()'d when the function is done executing. This matches the behavior of dispatch queues,
and ensures that the WorkQueue object won't go away while dispatched functions are running.

* Platform/CoreIPC/Connection.cpp:
(CoreIPC::Connection::Connection):
(CoreIPC::Connection::~Connection):
(CoreIPC::Connection::addQueueClient):
(CoreIPC::Connection::removeQueueClient):
(CoreIPC::Connection::invalidate):
(CoreIPC::Connection::sendMessage):
(CoreIPC::Connection::postConnectionDidCloseOnConnectionWorkQueue):
(CoreIPC::Connection::connectionDidClose):
* Platform/CoreIPC/Connection.h:
(Connection):
* Platform/CoreIPC/mac/ConnectionMac.cpp:
(CoreIPC::createDataAvailableSource):
(CoreIPC::Connection::open):
(CoreIPC::Connection::initializeDeadNameSource):
* Platform/WorkQueue.cpp:
(WorkQueue::create):
(WorkQueue::WorkQueue):
(WorkQueue::~WorkQueue):
* Platform/WorkQueue.h:
(WorkQueue):
* Platform/mac/WorkQueueMac.cpp:
(WorkQueue::dispatch):
(WorkQueue::dispatchAfterDelay):
* Shared/ChildProcess.cpp:
(WebKit::didCloseOnConnectionWorkQueue):
* UIProcess/Launcher/ProcessLauncher.cpp:
(WebKit::processLauncherWorkQueue):
(WebKit::ProcessLauncher::ProcessLauncher):
* UIProcess/WebProcessProxy.cpp:
(WebKit::pluginWorkQueue):
(WebKit::WebProcessProxy::getPlugins):

Modified Paths

Diff

Modified: trunk/Source/WebKit2/ChangeLog (141496 => 141497)


--- trunk/Source/WebKit2/ChangeLog	2013-01-31 23:38:04 UTC (rev 141496)
+++ trunk/Source/WebKit2/ChangeLog	2013-01-31 23:43:21 UTC (rev 141497)
@@ -1,3 +1,47 @@
+2013-01-31  Anders Carlsson  <[email protected]>
+
+        WorkQueue should be a ref-counted class
+        https://bugs.webkit.org/show_bug.cgi?id=108544
+
+        Reviewed by Sam Weinig.
+
+        Make WorkQueue a ref-counted class that's implicitly ref()'d when dispatching a function to it, and then
+        implicitly deref()'d when the function is done executing. This matches the behavior of dispatch queues,
+        and ensures that the WorkQueue object won't go away while dispatched functions are running.
+
+        * Platform/CoreIPC/Connection.cpp:
+        (CoreIPC::Connection::Connection):
+        (CoreIPC::Connection::~Connection):
+        (CoreIPC::Connection::addQueueClient):
+        (CoreIPC::Connection::removeQueueClient):
+        (CoreIPC::Connection::invalidate):
+        (CoreIPC::Connection::sendMessage):
+        (CoreIPC::Connection::postConnectionDidCloseOnConnectionWorkQueue):
+        (CoreIPC::Connection::connectionDidClose):
+        * Platform/CoreIPC/Connection.h:
+        (Connection):
+        * Platform/CoreIPC/mac/ConnectionMac.cpp:
+        (CoreIPC::createDataAvailableSource):
+        (CoreIPC::Connection::open):
+        (CoreIPC::Connection::initializeDeadNameSource):
+        * Platform/WorkQueue.cpp:
+        (WorkQueue::create):
+        (WorkQueue::WorkQueue):
+        (WorkQueue::~WorkQueue):
+        * Platform/WorkQueue.h:
+        (WorkQueue):
+        * Platform/mac/WorkQueueMac.cpp:
+        (WorkQueue::dispatch):
+        (WorkQueue::dispatchAfterDelay):
+        * Shared/ChildProcess.cpp:
+        (WebKit::didCloseOnConnectionWorkQueue):
+        * UIProcess/Launcher/ProcessLauncher.cpp:
+        (WebKit::processLauncherWorkQueue):
+        (WebKit::ProcessLauncher::ProcessLauncher):
+        * UIProcess/WebProcessProxy.cpp:
+        (WebKit::pluginWorkQueue):
+        (WebKit::WebProcessProxy::getPlugins):
+
 2013-01-31  Rafael Brandao  <[email protected]>
 
         [Qt][WK2] Fix build after removal of MessageID.h

Modified: trunk/Source/WebKit2/Platform/CoreIPC/Connection.cpp (141496 => 141497)


--- trunk/Source/WebKit2/Platform/CoreIPC/Connection.cpp	2013-01-31 23:38:04 UTC (rev 141496)
+++ trunk/Source/WebKit2/Platform/CoreIPC/Connection.cpp	2013-01-31 23:43:21 UTC (rev 141497)
@@ -222,7 +222,7 @@
     , m_shouldExitOnSyncMessageSendFailure(false)
     , m_didCloseOnConnectionWorkQueueCallback(0)
     , m_isConnected(false)
-    , m_connectionQueue("com.apple.CoreIPC.ReceiveQueue")
+    , m_connectionQueue(WorkQueue::create("com.apple.CoreIPC.ReceiveQueue"))
     , m_clientRunLoop(clientRunLoop)
     , m_inDispatchMessageCount(0)
     , m_inDispatchMessageMarkedDispatchWhenWaitingForSyncReplyCount(0)
@@ -238,8 +238,6 @@
 Connection::~Connection()
 {
     ASSERT(!isValid());
-
-    m_connectionQueue.invalidate();
 }
 
 void Connection::setOnlySendMessagesAsDispatchWhenWaitingForSyncReplyWhenProcessingSuchAMessage(bool flag)
@@ -258,12 +256,12 @@
 
 void Connection::addQueueClient(QueueClient* queueClient)
 {
-    m_connectionQueue.dispatch(WTF::bind(&Connection::addQueueClientOnWorkQueue, this, queueClient));
+    m_connectionQueue->dispatch(WTF::bind(&Connection::addQueueClientOnWorkQueue, this, queueClient));
 }
 
 void Connection::removeQueueClient(QueueClient* queueClient)
 {
-    m_connectionQueue.dispatch(WTF::bind(&Connection::removeQueueClientOnWorkQueue, this, queueClient));
+    m_connectionQueue->dispatch(WTF::bind(&Connection::removeQueueClientOnWorkQueue, this, queueClient));
 }
 
 void Connection::addQueueClientOnWorkQueue(QueueClient* queueClient)
@@ -296,7 +294,7 @@
     // Reset the client.
     m_client = 0;
 
-    m_connectionQueue.dispatch(WTF::bind(&Connection::platformInvalidate, this));
+    m_connectionQueue->dispatch(WTF::bind(&Connection::platformInvalidate, this));
 }
 
 void Connection::markCurrentlyDispatchedMessageAsInvalid()
@@ -336,7 +334,7 @@
     }
     
     // FIXME: We should add a boolean flag so we don't call this when work has already been scheduled.
-    m_connectionQueue.dispatch(WTF::bind(&Connection::sendOutgoingMessages, this));
+    m_connectionQueue->dispatch(WTF::bind(&Connection::sendOutgoingMessages, this));
     return true;
 }
 
@@ -617,7 +615,7 @@
 
 void Connection::postConnectionDidCloseOnConnectionWorkQueue()
 {
-    m_connectionQueue.dispatch(WTF::bind(&Connection::connectionDidClose, this));
+    m_connectionQueue->dispatch(WTF::bind(&Connection::connectionDidClose, this));
 }
 
 void Connection::connectionDidClose()
@@ -639,7 +637,7 @@
     }
 
     if (m_didCloseOnConnectionWorkQueueCallback)
-        m_didCloseOnConnectionWorkQueueCallback(m_connectionQueue, this);
+        m_didCloseOnConnectionWorkQueueCallback(m_connectionQueue.get(), this);
 
     m_clientRunLoop->dispatch(WTF::bind(&Connection::dispatchConnectionDidClose, this));
 }

Modified: trunk/Source/WebKit2/Platform/CoreIPC/Connection.h (141496 => 141497)


--- trunk/Source/WebKit2/Platform/CoreIPC/Connection.h	2013-01-31 23:38:04 UTC (rev 141496)
+++ trunk/Source/WebKit2/Platform/CoreIPC/Connection.h	2013-01-31 23:43:21 UTC (rev 141497)
@@ -161,7 +161,7 @@
     // In the future we might want a more generic way to handle sync or async messages directly
     // on the work queue, for example if we want to handle them on some other thread we could avoid
     // handling the message on the client thread first.
-    typedef void (*DidCloseOnConnectionWorkQueueCallback)(WorkQueue&, Connection*);
+    typedef void (*DidCloseOnConnectionWorkQueueCallback)(WorkQueue*, Connection*);
     void setDidCloseOnConnectionWorkQueueCallback(DidCloseOnConnectionWorkQueueCallback callback);
 
     void addQueueClient(QueueClient*);
@@ -234,7 +234,7 @@
     DidCloseOnConnectionWorkQueueCallback m_didCloseOnConnectionWorkQueueCallback;
 
     bool m_isConnected;
-    WorkQueue m_connectionQueue;
+    RefPtr<WorkQueue> m_connectionQueue;
     WebCore::RunLoop* m_clientRunLoop;
 
     Vector<QueueClient*> m_connectionQueueClients;

Modified: trunk/Source/WebKit2/Platform/CoreIPC/mac/ConnectionMac.cpp (141496 => 141497)


--- trunk/Source/WebKit2/Platform/CoreIPC/mac/ConnectionMac.cpp	2013-01-31 23:38:04 UTC (rev 141496)
+++ trunk/Source/WebKit2/Platform/CoreIPC/mac/ConnectionMac.cpp	2013-01-31 23:43:21 UTC (rev 141497)
@@ -105,9 +105,9 @@
 #endif
 }
 
-static dispatch_source_t createDataAvailableSource(mach_port_t receivePort, const WorkQueue& workQueue, const Function<void()>& function)
+static dispatch_source_t createDataAvailableSource(mach_port_t receivePort, WorkQueue* workQueue, const Function<void()>& function)
 {
-    dispatch_source_t source = dispatch_source_create(DISPATCH_SOURCE_TYPE_MACH_RECV, receivePort, 0, workQueue.dispatchQueue());
+    dispatch_source_t source = dispatch_source_create(DISPATCH_SOURCE_TYPE_MACH_RECV, receivePort, 0, workQueue->dispatchQueue());
     dispatch_source_set_event_handler(source, function);
     dispatch_source_set_cancel_handler(source, ^{
         mach_port_mod_refs(mach_task_self(), receivePort, MACH_PORT_RIGHT_RECEIVE, -1);
@@ -145,12 +145,12 @@
     setMachPortQueueLength(m_receivePort, MACH_PORT_QLIMIT_LARGE);
 
     // Register the data available handler.
-    m_receivePortDataAvailableSource = createDataAvailableSource(m_receivePort, m_connectionQueue, bind(&Connection::receiveSourceEventHandler, this));
+    m_receivePortDataAvailableSource = createDataAvailableSource(m_receivePort, m_connectionQueue.get(), bind(&Connection::receiveSourceEventHandler, this));
     dispatch_resume(m_receivePortDataAvailableSource);
 
     // If we have an exception port, register the data available handler and send over the port to the other end.
     if (m_exceptionPort) {
-        m_exceptionPortDataAvailableSource = createDataAvailableSource(m_exceptionPort, m_connectionQueue, bind(&Connection::exceptionSourceEventHandler, this));
+        m_exceptionPortDataAvailableSource = createDataAvailableSource(m_exceptionPort, m_connectionQueue.get(), bind(&Connection::exceptionSourceEventHandler, this));
         dispatch_resume(m_exceptionPortDataAvailableSource);
 
         OwnPtr<MessageEncoder> encoder = MessageEncoder::create("IPC", "SetExceptionPort", 0);
@@ -271,7 +271,7 @@
 
 void Connection::initializeDeadNameSource()
 {
-    m_deadNameSource = dispatch_source_create(DISPATCH_SOURCE_TYPE_MACH_SEND, m_sendPort, 0, m_connectionQueue.dispatchQueue());
+    m_deadNameSource = dispatch_source_create(DISPATCH_SOURCE_TYPE_MACH_SEND, m_sendPort, 0, m_connectionQueue->dispatchQueue());
     dispatch_source_set_event_handler(m_deadNameSource, bind(&Connection::connectionDidClose, this));
 
     mach_port_t sendPort = m_sendPort;

Modified: trunk/Source/WebKit2/Platform/WorkQueue.cpp (141496 => 141497)


--- trunk/Source/WebKit2/Platform/WorkQueue.cpp	2013-01-31 23:38:04 UTC (rev 141496)
+++ trunk/Source/WebKit2/Platform/WorkQueue.cpp	2013-01-31 23:43:21 UTC (rev 141497)
@@ -26,26 +26,17 @@
 #include "config.h"
 #include "WorkQueue.h"
 
+PassRefPtr<WorkQueue> WorkQueue::create(const char* name)
+{
+    return adoptRef(new WorkQueue(name));
+}
+
 WorkQueue::WorkQueue(const char* name)
-    : m_isValid(true)
 {
     platformInitialize(name);
 }
 
 WorkQueue::~WorkQueue()
 {
-#if !ASSERT_DISABLED
-    MutexLocker locker(m_isValidMutex);
-    ASSERT(!m_isValid);
-#endif
-}
-
-void WorkQueue::invalidate()
-{
-    {
-        MutexLocker locker(m_isValidMutex);
-        m_isValid = false;
-    }
-
     platformInvalidate();
 }

Modified: trunk/Source/WebKit2/Platform/WorkQueue.h (141496 => 141497)


--- trunk/Source/WebKit2/Platform/WorkQueue.h	2013-01-31 23:38:04 UTC (rev 141496)
+++ trunk/Source/WebKit2/Platform/WorkQueue.h	2013-01-31 23:43:21 UTC (rev 141497)
@@ -58,11 +58,9 @@
 #include <Ecore.h>
 #endif
 
-class WorkQueue {
-    WTF_MAKE_NONCOPYABLE(WorkQueue);
-
+class WorkQueue : public ThreadSafeRefCounted<WorkQueue> {
 public:
-    explicit WorkQueue(const char* name);
+    static PassRefPtr<WorkQueue> create(const char* name);
     ~WorkQueue();
 
     // Will dispatch the given function to run as soon as possible.
@@ -71,8 +69,6 @@
     // Will dispatch the given function after the given delay (in seconds).
     void dispatchAfterDelay(const Function<void()>&, double delay);
 
-    void invalidate();
-
 #if OS(DARWIN)
     dispatch_queue_t dispatchQueue() const { return m_dispatchQueue; }
 
@@ -92,9 +88,7 @@
 #endif
 
 private:
-    // FIXME: Use an atomic boolean here instead.
-    Mutex m_isValidMutex;
-    bool m_isValid;
+    explicit WorkQueue(const char* name);
 
     void platformInitialize(const char* name);
     void platformInvalidate();

Modified: trunk/Source/WebKit2/Platform/mac/WorkQueueMac.cpp (141496 => 141497)


--- trunk/Source/WebKit2/Platform/mac/WorkQueueMac.cpp	2013-01-31 23:38:04 UTC (rev 141496)
+++ trunk/Source/WebKit2/Platform/mac/WorkQueueMac.cpp	2013-01-31 23:43:21 UTC (rev 141497)
@@ -26,43 +26,28 @@
 #include "config.h"
 #include "WorkQueue.h"
 
-#include <mach/mach_init.h>
-#include <mach/mach_port.h>
-#include <wtf/PassOwnPtr.h>
-
-struct WorkQueueAndFunction {
-    WorkQueueAndFunction(WorkQueue* workQueue, const Function<void()>& function)
-        : workQueue(workQueue)
-        , function(function)
-    {
-    }
-
-    WorkQueue* workQueue;
-    Function<void()> function;
-};
-
-void WorkQueue::executeFunction(void* context)
+void WorkQueue::dispatch(const Function<void()>& function)
 {
-    OwnPtr<WorkQueueAndFunction> workQueueAndFunction = adoptPtr(static_cast<WorkQueueAndFunction*>(context));
-    
-    {
-        MutexLocker locker(workQueueAndFunction->workQueue->m_isValidMutex);
-        if (!workQueueAndFunction->workQueue->m_isValid)
-            return;
-    }
+    Function<void()> functionCopy = function;
 
-    (workQueueAndFunction->function)();
+    ref();
+    dispatch_async(m_dispatchQueue, ^{
+        functionCopy();
+        deref();
+    });
 }
 
-void WorkQueue::dispatch(const Function<void()>& function)
-{
-    dispatch_async_f(m_dispatchQueue, new WorkQueueAndFunction(this, function), executeFunction);
-}
-
 void WorkQueue::dispatchAfterDelay(const Function<void()>& function, double delay)
 {
     dispatch_time_t delayTime = dispatch_time(DISPATCH_TIME_NOW, delay * NSEC_PER_SEC);
-    dispatch_after_f(delayTime, m_dispatchQueue, new WorkQueueAndFunction(this, function), executeFunction);
+
+    Function<void()> functionCopy = function;
+
+    ref();
+    dispatch_after(delayTime, m_dispatchQueue, ^{
+        functionCopy();
+        deref();
+    });
 }
 
 void WorkQueue::platformInitialize(const char* name)

Modified: trunk/Source/WebKit2/Shared/ChildProcess.cpp (141496 => 141497)


--- trunk/Source/WebKit2/Shared/ChildProcess.cpp	2013-01-31 23:38:04 UTC (rev 141496)
+++ trunk/Source/WebKit2/Shared/ChildProcess.cpp	2013-01-31 23:43:21 UTC (rev 141497)
@@ -55,13 +55,13 @@
     _exit(EXIT_FAILURE);
 }
 
-static void didCloseOnConnectionWorkQueue(WorkQueue& workQueue, CoreIPC::Connection*)
+static void didCloseOnConnectionWorkQueue(WorkQueue* workQueue, CoreIPC::Connection*)
 {
     // If the connection has been closed and we haven't responded in the main thread for 10 seconds
     // the process will exit forcibly.
     const double watchdogDelay = 10;
 
-    workQueue.dispatchAfterDelay(bind(static_cast<void(*)()>(watchdogCallback)), watchdogDelay);
+    workQueue->dispatchAfterDelay(bind(static_cast<void(*)()>(watchdogCallback)), watchdogDelay);
 }
 
 void ChildProcess::initialize(const ChildProcessInitializationParameters& parameters)

Modified: trunk/Source/WebKit2/UIProcess/Launcher/ProcessLauncher.cpp (141496 => 141497)


--- trunk/Source/WebKit2/UIProcess/Launcher/ProcessLauncher.cpp	2013-01-31 23:38:04 UTC (rev 141496)
+++ trunk/Source/WebKit2/UIProcess/Launcher/ProcessLauncher.cpp	2013-01-31 23:43:21 UTC (rev 141497)
@@ -31,11 +31,9 @@
 
 namespace WebKit {
 
-static WorkQueue& processLauncherWorkQueue()
+static WorkQueue* processLauncherWorkQueue()
 {
-    // Give in to VisualStudio and its 31 character thread name limit and shorten the thread name to ProcLauncher instead of class name.
-    // See createThread() in Threading.cpp.
-    DEFINE_STATIC_LOCAL(WorkQueue, processLauncherWorkQueue, ("com.apple.WebKit.ProcLauncher"));
+    static WorkQueue* processLauncherWorkQueue = WorkQueue::create("com.apple.WebKit.ProcessLauncher").leakRef();
     return processLauncherWorkQueue;
 }
 
@@ -46,7 +44,7 @@
 {
     // Launch the process.
     m_isLaunching = true;
-    processLauncherWorkQueue().dispatch(bind(&ProcessLauncher::launchProcess, this));
+    processLauncherWorkQueue()->dispatch(bind(&ProcessLauncher::launchProcess, this));
 }
 
 void ProcessLauncher::didFinishLaunchingProcess(PlatformProcessIdentifier processIdentifier, CoreIPC::Connection::Identifier identifier)

Modified: trunk/Source/WebKit2/UIProcess/WebProcessProxy.cpp (141496 => 141497)


--- trunk/Source/WebKit2/UIProcess/WebProcessProxy.cpp	2013-01-31 23:38:04 UTC (rev 141496)
+++ trunk/Source/WebKit2/UIProcess/WebProcessProxy.cpp	2013-01-31 23:43:21 UTC (rev 141497)
@@ -89,10 +89,10 @@
 }
 
 #if ENABLE(NETSCAPE_PLUGIN_API)
-static WorkQueue& pluginWorkQueue()
+static WorkQueue* pluginWorkQueue()
 {
-    DEFINE_STATIC_LOCAL(WorkQueue, queue, ("com.apple.CoreIPC.PluginQueue"));
-    return queue;
+    static WorkQueue* pluginWorkQueue = WorkQueue::create("com.apple.WebKit.PluginQueue").leakRef();
+    return pluginWorkQueue;
 }
 #endif // ENABLE(NETSCAPE_PLUGIN_API)
 
@@ -348,7 +348,7 @@
 
 void WebProcessProxy::getPlugins(CoreIPC::Connection*, uint64_t requestID, bool refresh)
 {
-    pluginWorkQueue().dispatch(bind(&WebProcessProxy::handleGetPlugins, this, requestID, refresh));
+    pluginWorkQueue()->dispatch(bind(&WebProcessProxy::handleGetPlugins, this, requestID, refresh));
 }
 
 #endif // ENABLE(NETSCAPE_PLUGIN_API)
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to