You are viewing a plain text version of this content. The canonical link for it is here.
Posted to server-dev@james.apache.org by er...@apache.org on 2013/04/26 14:44:30 UTC

svn commit: r1476172 - /james/mailbox/trunk/store/src/main/java/org/apache/james/mailbox/store/AbstractDelegatingMailboxListener.java

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: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org