Fix deadlock when selecting encrypt
authorAndre Heinecke <aheinecke@intevation.de>
Mon, 8 Oct 2018 13:19:58 +0000 (15:19 +0200)
committerAndre Heinecke <aheinecke@intevation.de>
Mon, 8 Oct 2018 13:19:58 +0000 (15:19 +0200)
* src/mail.cpp (Mail::locateAllCryptoRecipients_o): Use a copy
of the mail map instead of a locked instance.

--
Locking the mail map for a complex operation is a bad
idea. What happened here is that locateKeys_o can start
different threads and those threads can use "Mail::isValidPtr" which
uses the s_mail_map and locks it accordingly.
So there is a deadlock.

src/mail.cpp

index 9796834..82c9259 100644 (file)
@@ -3413,14 +3413,15 @@ Mail::locateAllCryptoRecipients_o ()
   TSTART;
   gpgrt_lock_lock (&mail_map_lock);
   std::map<LPDISPATCH, Mail *>::iterator it;
-  for (it = s_mail_map.begin(); it != s_mail_map.end(); ++it)
+  auto mail_map_copy = s_mail_map;
+  gpgrt_lock_unlock (&mail_map_lock);
+  for (it = mail_map_copy.begin(); it != mail_map_copy.end(); ++it)
     {
       if (it->second->needs_crypto_m ())
         {
           it->second->locateKeys_o ();
         }
     }
-  gpgrt_lock_unlock (&mail_map_lock);
   TRETURN;
 }