TransactionOperations can get destroyed on the wrong thread.
authorbeidson@apple.com <beidson@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 5 Jul 2016 18:04:28 +0000 (18:04 +0000)
committerbeidson@apple.com <beidson@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 5 Jul 2016 18:04:28 +0000 (18:04 +0000)
https://bugs.webkit.org/show_bug.cgi?id=159103

Reviewed by Alex Christensen.

No new tests (Very racy, not feasible to write a dedicated test for, caught on bots occasionally as-is).

* Modules/indexeddb/IDBActiveDOMObject.h:
(WebCore::IDBActiveDOMObject::callFunctionOnOriginThread):

* Modules/indexeddb/client/IDBConnectionProxy.cpp:
(WebCore::IDBClient::IDBConnectionProxy::completeOperation): Pass the last ref to the operation to its
  origin thread to be deleted there.

* Modules/indexeddb/client/TransactionOperation.h:
(WebCore::IDBClient::TransactionOperation::performCompleteOnOriginThread):

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

Source/WebCore/ChangeLog
Source/WebCore/Modules/indexeddb/IDBActiveDOMObject.h
Source/WebCore/Modules/indexeddb/client/IDBConnectionProxy.cpp
Source/WebCore/Modules/indexeddb/client/TransactionOperation.h

index 28dc34f..efc8210 100644 (file)
@@ -1,3 +1,22 @@
+2016-07-05  Brady Eidson  <beidson@apple.com>
+
+        TransactionOperations can get destroyed on the wrong thread.
+        https://bugs.webkit.org/show_bug.cgi?id=159103
+
+        Reviewed by Alex Christensen.
+
+        No new tests (Very racy, not feasible to write a dedicated test for, caught on bots occasionally as-is).
+
+        * Modules/indexeddb/IDBActiveDOMObject.h:
+        (WebCore::IDBActiveDOMObject::callFunctionOnOriginThread):
+        
+        * Modules/indexeddb/client/IDBConnectionProxy.cpp:
+        (WebCore::IDBClient::IDBConnectionProxy::completeOperation): Pass the last ref to the operation to its
+          origin thread to be deleted there.
+        
+        * Modules/indexeddb/client/TransactionOperation.h:
+        (WebCore::IDBClient::TransactionOperation::performCompleteOnOriginThread):
+
 2016-07-05  Youenn Fablet  <youenn@apple.com>
 
         Remove CredentialRequest ResourceLoaderOptions
index 842dce4..2d0c9eb 100644 (file)
@@ -63,6 +63,22 @@ public:
         context->postCrossThreadTask(object, method, arguments...);
     }
 
+    void callFunctionOnOriginThread(Function<void ()>&& function)
+    {
+        if (originThreadID() == currentThread()) {
+            function();
+            return;
+        }
+
+        Locker<Lock> lock(m_scriptExecutionContextLock);
+
+        ScriptExecutionContext* context = scriptExecutionContext();
+        if (!context)
+            return;
+
+        context->postTask(WTFMove(function));
+    }
+
 protected:
     IDBActiveDOMObject(ScriptExecutionContext* context)
         : ActiveDOMObject(context)
index 8363619..b3c74dc 100644 (file)
@@ -223,7 +223,7 @@ void IDBConnectionProxy::completeOperation(const IDBResultData& resultData)
     if (!operation)
         return;
 
-    operation->performCompleteOnOriginThread(resultData);
+    operation->performCompleteOnOriginThread(resultData, WTFMove(operation));
 }
 
 void IDBConnectionProxy::abortOpenAndUpgradeNeeded(uint64_t databaseConnectionIdentifier, const IDBResourceIdentifier& transactionIdentifier)
index c7a19dc..bf07bbc 100644 (file)
@@ -62,14 +62,17 @@ public:
         m_performFunction = { };
     }
 
-    void performCompleteOnOriginThread(const IDBResultData& data)
+    void performCompleteOnOriginThread(const IDBResultData& data, RefPtr<TransactionOperation>&& lastRef)
     {
         ASSERT(isMainThread());
 
         if (m_originThreadID == currentThread())
             completed(data);
-        else
+        else {
             m_transaction->performCallbackOnOriginThread(*this, &TransactionOperation::completed, data);
+            m_transaction->callFunctionOnOriginThread([lastRef = WTFMove(lastRef)]() {
+            });
+        }
     }
 
     void completed(const IDBResultData& data)