Author: eric
Date: Fri Apr 26 12:44:30 2013
New Revision: 1476172

URL: http://svn.apache.org/r1476172
Log:
Fix deadlock in AbstractDelegatingMailboxListener under load, patch contributed 
by Andrzej Rusin (IMAP-372)

Modified:
    
james/mailbox/trunk/store/src/main/java/org/apache/james/mailbox/store/AbstractDelegatingMailboxListener.java

Modified: 
james/mailbox/trunk/store/src/main/java/org/apache/james/mailbox/store/AbstractDelegatingMailboxListener.java
URL: 
http://svn.apache.org/viewvc/james/mailbox/trunk/store/src/main/java/org/apache/james/mailbox/store/AbstractDelegatingMailboxListener.java?rev=1476172&r1=1476171&r2=1476172&view=diff
==============================================================================
--- 
james/mailbox/trunk/store/src/main/java/org/apache/james/mailbox/store/AbstractDelegatingMailboxListener.java
 (original)
+++ 
james/mailbox/trunk/store/src/main/java/org/apache/james/mailbox/store/AbstractDelegatingMailboxListener.java
 Fri Apr 26 12:44:30 2013
@@ -40,16 +40,12 @@ public abstract class AbstractDelegating
     public void event(Event event) {
         MailboxPath path = event.getMailboxPath();
         Map<MailboxPath, List<MailboxListener>> listeners = getListeners();
+        List<MailboxListener> mListeners = null;
         synchronized (listeners) {
-            List<MailboxListener> mListeners = listeners.get(path);
+            mListeners = listeners.get(path);
             if (mListeners != null && mListeners.isEmpty() == false) {
-                
-                int sz = mListeners.size();
-                for (int i = 0; i < sz; i++) {
-                    MailboxListener l = mListeners.get(i);
-                    l.event(event);
-                    
-                }
+             // take snapshot of the listeners list for later
+                mListeners = new ArrayList<MailboxListener>(mListeners);
                 
                 if (event instanceof MailboxDeletion) {
                     // remove listeners if the mailbox was deleted
@@ -63,17 +59,24 @@ public abstract class AbstractDelegating
                     }
                 }
                 
-            }  
+            }
             
         }
-        
+        //outside the synchronized block against deadlocks from propagated 
events wanting to lock the listeners
+        if (mListeners != null) {
+            int sz = mListeners.size();
+            for (int i = 0; i < sz; i++) {
+                MailboxListener l = mListeners.get(i);
+                l.event(event);
+            }
+        }
         
         List<MailboxListener> globalListeners = getGlobalListeners();
         if (globalListeners != null) {
             synchronized (globalListeners) {
                 if (globalListeners.isEmpty() == false) {
                     List<MailboxListener> closedListener = new 
ArrayList<MailboxListener>();
-                    
+                    //TODO do not fire them inside synchronized block too?
                     int sz = globalListeners.size();
                     for (int i = 0; i < sz; i++) {
                         MailboxListener l = globalListeners.get(i);



---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to