Bug 1386601 - experimental patch to investigate Thunderbird topcrash, serializes S/MIME verification. rs=jorgk
authorKai Engert <kaie@kuix.de>
Tue, 15 Jan 2019 09:57:00 +0100
changeset 34209 279f3823f22354595e65d3327b39627ac838320d
parent 34208 ee93a8e6c6322b2f5c54af5ffe96d18726183fd6
child 34210 4c0e476ae8188300310bff6fe6f2614cc3a17a23
push id389
push userclokep@gmail.com
push dateMon, 18 Mar 2019 19:01:53 +0000
reviewersjorgk
bugs1386601
Bug 1386601 - experimental patch to investigate Thunderbird topcrash, serializes S/MIME verification. rs=jorgk
mailnews/mime/src/nsCMS.cpp
--- a/mailnews/mime/src/nsCMS.cpp
+++ b/mailnews/mime/src/nsCMS.cpp
@@ -338,21 +338,33 @@ public:
                         unsigned char *aDigestData, uint32_t aDigestDataLen)
   {
     MOZ_ASSERT(NS_IsMainThread());
     mMessage = aMessage;
     mListener = aListener;
     mDigestData.Assign(reinterpret_cast<char *>(aDigestData), aDigestDataLen);
   }
 
+  static void InitStaticLock()
+  {
+    // If we ensure this is only executed on the main thread, we know
+    // there cannot be a race to allocate the lock multiple times.
+    MOZ_ASSERT(NS_IsMainThread());
+    if (!mLock) {
+      // Deliberate leak, one time allocation.
+      mLock = new mozilla::Mutex("SMimeVerificationTask");
+    }
+  }
+
 private:
   virtual nsresult CalculateResult() override
   {
     MOZ_ASSERT(!NS_IsMainThread());
 
+    MutexAutoLock mon(*mLock);
     nsresult rv;
     if (!mDigestData.IsEmpty()) {
       rv = mMessage->VerifyDetachedSignature(
         reinterpret_cast<uint8_t*>(const_cast<char *>(mDigestData.get())),
         mDigestData.Length());
     } else {
       rv = mMessage->VerifySignature();
     }
@@ -365,21 +377,26 @@ private:
 
     nsCOMPtr<nsICMSMessage2> m2 = do_QueryInterface(mMessage);
     mListener->Notify(m2, rv);
   }
 
   nsCOMPtr<nsICMSMessage> mMessage;
   nsCOMPtr<nsISMimeVerificationListener> mListener;
   nsCString mDigestData;
+
+  static mozilla::Mutex *mLock;
 };
 
+mozilla::Mutex * SMimeVerificationTask::mLock = nullptr;
+
 nsresult nsCMSMessage::CommonAsyncVerifySignature(nsISMimeVerificationListener *aListener,
                                                   unsigned char* aDigestData, uint32_t aDigestDataLen)
 {
+  SMimeVerificationTask::InitStaticLock();
   RefPtr<CryptoTask> task = new SMimeVerificationTask(this, aListener, aDigestData, aDigestDataLen);
   return task->Dispatch("SMimeVerify");
 }
 
 class nsZeroTerminatedCertArray
 {
 public:
   nsZeroTerminatedCertArray()