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