OSDN Git Service

Fix a rare crash when dispatching icon notifications.
authorPatrick Scott <phanna@android.com>
Mon, 14 Dec 2009 21:17:25 +0000 (16:17 -0500)
committerPatrick Scott <phanna@android.com>
Mon, 14 Dec 2009 21:19:22 +0000 (16:19 -0500)
I believe this happened when a WebIconDatabaseClient registered twice for
notifications. When it unregistered, it only removed the first entry. This could
lead to a crash since the second entry would be pointing to possibly deleted
memory.

Remove the mutex protection since all operations on mClients happen in the same
thread.

Add a missing include file in WebHistory found while debugging this crash.

Bug: 2279055

WebKit/android/jni/WebHistory.cpp
WebKit/android/jni/WebIconDatabase.cpp
WebKit/android/jni/WebIconDatabase.h

index f722db7..76a310b 100644 (file)
@@ -44,6 +44,7 @@
 #include "TextEncoding.h"
 #include "WebCoreFrameBridge.h"
 #include "WebCoreJni.h"
+#include "WebIconDatabase.h"
 #include "jni_utility.h"
 
 #include <JNIHelp.h>
index e15d179..20258a4 100644 (file)
@@ -67,10 +67,6 @@ static WebIconDatabase* gIconDatabaseClient = new WebIconDatabase();
 // XXX: Called by the IconDatabase thread
 void WebIconDatabase::dispatchDidAddIconForPageURL(const WebCore::String& pageURL)
 {
-    // If there are no clients currently, drop this message.
-    if (mClients.size() == 0)
-        return;
-
     mNotificationsMutex.lock();
     mNotifications.append(pageURL);
     if (!mDeliveryRequested) {
@@ -83,23 +79,25 @@ void WebIconDatabase::dispatchDidAddIconForPageURL(const WebCore::String& pageUR
 // Called in the WebCore thread
 void WebIconDatabase::RegisterForIconNotification(WebIconDatabaseClient* client)
 {
-    gIconDatabaseClient->mClientsMutex.lock();
+    WebIconDatabase* db = gIconDatabaseClient;
+    for (unsigned i = 0; i < db->mClients.size(); ++i) {
+        // Do not add the same client twice.
+        if (db->mClients[i] == client)
+            return;
+    }
     gIconDatabaseClient->mClients.append(client);
-    gIconDatabaseClient->mClientsMutex.unlock();
 }
 
 // Called in the WebCore thread
 void WebIconDatabase::UnregisterForIconNotification(WebIconDatabaseClient* client)
 {
     WebIconDatabase* db = gIconDatabaseClient;
-    db->mClientsMutex.lock();
     for (unsigned i = 0; i < db->mClients.size(); ++i) {
         if (db->mClients[i] == client) {
             db->mClients.remove(i);
             break;
         }
     }
-    db->mClientsMutex.unlock();
 }
 
 // Called in the WebCore thread
@@ -123,9 +121,7 @@ void WebIconDatabase::deliverNotifications()
 
     // Swap the clients queue
     Vector<WebIconDatabaseClient*> clients;
-    mClientsMutex.lock();
     clients.swap(mClients);
-    mClientsMutex.unlock();
 
     for (unsigned i = 0; i < queue.size(); ++i) {
         for (unsigned j = 0; j < clients.size(); ++j) {
index 743c5eb..c91c4ae 100644 (file)
@@ -59,9 +59,8 @@ namespace android {
         // Deliver all the icon notifications
         void deliverNotifications();
 
-        // List of clients and a mutex to protect it.
+        // List of clients.
         Vector<WebIconDatabaseClient*> mClients;
-        android::Mutex                 mClientsMutex;
 
         // Queue of page urls that have received an icon.
         Vector<WebCore::String> mNotifications;