[SCM] WebKit Debian packaging branch, debian/experimental, updated. upstream/1.3.3-9427-gc2be6fc

andersca at apple.com andersca at apple.com
Wed Dec 22 15:16:27 UTC 2010


The following commit has been merged in the debian/experimental branch:
commit 209c0f26c28ad81ca81ddd07a9f707313c547511
Author: andersca at apple.com <andersca at apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Fri Oct 29 17:22:26 2010 +0000

    Connection::sendSyncMessage needs to dispatch incoming sync messages
    https://bugs.webkit.org/show_bug.cgi?id=48606
    
    Reviewed by Adam Roben.
    
    * Platform/CoreIPC/Connection.cpp:
    (CoreIPC::Connection::sendSyncMessage):
    Protect the connection when waiting for a reply. Schedule for any remaining incoming sync messages
    to be sent once the bottom-most waitForSyncReply calls returns.
    
    (CoreIPC::Connection::waitForSyncReply):
    Make sure to dispatch any incoming sync messages.
    
    (CoreIPC::Connection::processIncomingMessage):
    If the incoming message is a sync message and we're waiting for a sync reply, add the message to the
    queue of "sync messages received while waiting for sync reply" and wake up the client thread.
    
    * Platform/CoreIPC/Connection.h:
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@70893 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/WebKit2/ChangeLog b/WebKit2/ChangeLog
index 7790e9c..93be2b7 100644
--- a/WebKit2/ChangeLog
+++ b/WebKit2/ChangeLog
@@ -116,6 +116,27 @@
 
         Reviewed by Adam Roben.
 
+        Connection::sendSyncMessage needs to dispatch incoming sync messages
+        https://bugs.webkit.org/show_bug.cgi?id=48606
+
+        * Platform/CoreIPC/Connection.cpp:
+        (CoreIPC::Connection::sendSyncMessage):
+        Protect the connection when waiting for a reply. Schedule for any remaining incoming sync messages
+        to be sent once the bottom-most waitForSyncReply calls returns.
+
+        (CoreIPC::Connection::waitForSyncReply):
+        Make sure to dispatch any incoming sync messages.
+
+        (CoreIPC::Connection::processIncomingMessage):
+        If the incoming message is a sync message and we're waiting for a sync reply, add the message to the
+        queue of "sync messages received while waiting for sync reply" and wake up the client thread.
+
+        * Platform/CoreIPC/Connection.h:
+
+2010-10-28  Anders Carlsson  <andersca at apple.com>
+
+        Reviewed by Adam Roben.
+
         Move code to dispatch a sync message out into a separate function
         https://bugs.webkit.org/show_bug.cgi?id=48605
 
diff --git a/WebKit2/Platform/CoreIPC/Connection.cpp b/WebKit2/Platform/CoreIPC/Connection.cpp
index c678d17..569ea23 100644
--- a/WebKit2/Platform/CoreIPC/Connection.cpp
+++ b/WebKit2/Platform/CoreIPC/Connection.cpp
@@ -176,7 +176,9 @@ PassOwnPtr<ArgumentDecoder> Connection::sendSyncMessage(MessageID messageID, uin
     // First send the message.
     sendMessage(messageID, encoder);
     
-    // Then wait for a reply.
+    // Then wait for a reply. Waiting for a reply could involve dispatching incoming sync messages, so
+    // keep an extra reference to the connection here in case it's invalidated.
+    RefPtr<Connection> protect(this);
     OwnPtr<ArgumentDecoder> reply = waitForSyncReply(syncRequestID, timeout);
 
     // Finally, pop the pending sync reply information.
@@ -184,6 +186,20 @@ PassOwnPtr<ArgumentDecoder> Connection::sendSyncMessage(MessageID messageID, uin
         MutexLocker locker(m_syncReplyStateMutex);
         ASSERT(m_pendingSyncReplies.last().syncRequestID == syncRequestID);
         m_pendingSyncReplies.removeLast();
+
+        if (m_pendingSyncReplies.isEmpty()) {
+            // This was the bottom-most sendSyncMessage call in the stack. If we have any pending incoming
+            // sync messages, they need to be dispatched.
+            if (!m_syncMessagesReceivedWhileWaitingForSyncReply.isEmpty()) {
+                // Add the messages.
+                MutexLocker locker(m_incomingMessagesLock);
+                m_incomingMessages.append(m_syncMessagesReceivedWhileWaitingForSyncReply);
+                m_syncMessagesReceivedWhileWaitingForSyncReply.clear();
+
+                // Schedule for the messages to be sent.
+                m_clientRunLoop->scheduleWork(WorkItem::create(this, &Connection::dispatchMessages));
+            }
+        }
     }
     
     return reply.release();
@@ -198,7 +214,25 @@ PassOwnPtr<ArgumentDecoder> Connection::waitForSyncReply(uint64_t syncRequestID,
         {
             MutexLocker locker(m_syncReplyStateMutex);
 
-            // First, check if there is a sync reply at the top of the stack.
+            // First, check if we have any incoming sync messages that we need to process.
+            Vector<IncomingMessage> syncMessagesReceivedWhileWaitingForSyncReply;
+            m_syncMessagesReceivedWhileWaitingForSyncReply.swap(syncMessagesReceivedWhileWaitingForSyncReply);
+
+            if (!syncMessagesReceivedWhileWaitingForSyncReply.isEmpty()) {
+                // Make sure to unlock the mutex here because we're calling out to client code which could in turn send
+                // another sync message and we don't want that to deadlock.
+                m_syncReplyStateMutex.unlock();
+                
+                for (size_t i = 0; i < syncMessagesReceivedWhileWaitingForSyncReply.size(); ++i) {
+                    IncomingMessage& message = syncMessagesReceivedWhileWaitingForSyncReply[i];
+                    OwnPtr<ArgumentDecoder> arguments = message.releaseArguments();
+
+                    dispatchSyncMessage(message.messageID(), arguments.get());
+                }
+                m_syncReplyStateMutex.lock();
+            }
+
+            // Second, check if there is a sync reply at the top of the stack.
             ASSERT(!m_pendingSyncReplies.isEmpty());
             
             PendingSyncReply& pendingSyncReply = m_pendingSyncReplies.last();
@@ -233,7 +267,21 @@ void Connection::processIncomingMessage(MessageID messageID, PassOwnPtr<Argument
         m_waitForSyncReplySemaphore.signal();
         return;
     }
-    
+
+    // Check if this is a sync message. If it is, and we're waiting for a sync reply this message
+    // needs to be dispatched. If we don't we'll end up with a deadlock where both sync message senders are
+    // stuck waiting for a reply.
+    if (messageID.isSync()) {
+        MutexLocker locker(m_syncReplyStateMutex);
+        if (!m_pendingSyncReplies.isEmpty()) {
+            m_syncMessagesReceivedWhileWaitingForSyncReply.append(IncomingMessage(messageID, arguments));
+
+            // The message has been added, now wake up the client thread.
+            m_waitForSyncReplySemaphore.signal();
+            return;
+        }
+    }
+        
     // Check if we're waiting for this message.
     {
         MutexLocker locker(m_waitForMessageMutex);
diff --git a/WebKit2/Platform/CoreIPC/Connection.h b/WebKit2/Platform/CoreIPC/Connection.h
index eeec26f..d63c234 100644
--- a/WebKit2/Platform/CoreIPC/Connection.h
+++ b/WebKit2/Platform/CoreIPC/Connection.h
@@ -232,6 +232,7 @@ private:
     Mutex m_syncReplyStateMutex;
     bool m_shouldWaitForSyncReplies;
     Vector<PendingSyncReply> m_pendingSyncReplies;
+    Vector<IncomingMessage> m_syncMessagesReceivedWhileWaitingForSyncReply;
 
 #if PLATFORM(MAC)
     // Called on the connection queue.

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list