This is an automated email from the ASF dual-hosted git repository.

btellier pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/james-project.git

commit 51f1440a7459223e572190c18fe2163229293f16
Author: Benoit TELLIER <btell...@linagora.com>
AuthorDate: Sun Nov 10 13:17:04 2024 +0100

    [FIX] IMAP IDLE: avoid data race between synchronous response and listener
---
 .../apache/james/imap/processor/IdleProcessor.java    | 19 +++++++++++++------
 1 file changed, 13 insertions(+), 6 deletions(-)

diff --git 
a/protocols/imap/src/main/java/org/apache/james/imap/processor/IdleProcessor.java
 
b/protocols/imap/src/main/java/org/apache/james/imap/processor/IdleProcessor.java
index 570a67120d..bca9315123 100644
--- 
a/protocols/imap/src/main/java/org/apache/james/imap/processor/IdleProcessor.java
+++ 
b/protocols/imap/src/main/java/org/apache/james/imap/processor/IdleProcessor.java
@@ -25,8 +25,10 @@ import static org.apache.james.util.ReactorUtils.logAsMono;
 import java.time.Duration;
 import java.util.List;
 import java.util.Locale;
+import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.atomic.AtomicBoolean;
 
+import com.github.fge.lambdas.Throwing;
 import jakarta.inject.Inject;
 
 import org.apache.james.events.Event;
@@ -80,18 +82,20 @@ public class IdleProcessor extends 
AbstractMailboxProcessor<IdleRequest> impleme
 
     @Override
     protected Mono<Void> processRequestReactive(IdleRequest request, 
ImapSession session, Responder responder) {
-        return Mono.fromRunnable(() -> idle(request,session, responder))
+        CountDownLatch countDownLatch = new CountDownLatch(1);
+        return Mono.fromRunnable(() -> idle(request, session, responder, 
countDownLatch))
             .then(unsolicitedResponses(session, responder, false))
             .onErrorResume(e -> {
                 no(request, responder, 
HumanReadableText.GENERIC_FAILURE_DURING_PROCESSING);
                 return logAsMono(() -> LOGGER.error("Encountered error 
executing IMAP IDLE", e));
-            });
+            })
+            .then(Mono.fromRunnable(countDownLatch::countDown));
     }
 
-    private void idle(IdleRequest request, ImapSession session, Responder 
responder) {
+    private void idle(IdleRequest request, ImapSession session, Responder 
responder, CountDownLatch countDownLatch) {
         SelectedMailbox sm = session.getSelected();
         if (sm != null) {
-            sm.registerIdle(new IdleMailboxListener(session, responder));
+            sm.registerIdle(new IdleMailboxListener(session, responder, 
countDownLatch));
         }
 
         final AtomicBoolean idleActive = new AtomicBoolean(true);
@@ -165,10 +169,12 @@ public class IdleProcessor extends 
AbstractMailboxProcessor<IdleRequest> impleme
 
         private final Responder responder;
         private final ImapSession session;
+        private final CountDownLatch countDownLatch;
 
-        public IdleMailboxListener(ImapSession session, Responder responder) {
+        public IdleMailboxListener(ImapSession session, Responder responder, 
CountDownLatch countDownLatch) {
             this.session = session;
             this.responder = responder;
+            this.countDownLatch = countDownLatch;
         }
 
         @Override
@@ -178,7 +184,8 @@ public class IdleProcessor extends 
AbstractMailboxProcessor<IdleRequest> impleme
 
         @Override
         public Publisher<Void> reactiveEvent(Event event) {
-            return unsolicitedResponses(session, responder, false)
+            return Mono.fromRunnable(Throwing.runnable(countDownLatch::await))
+                .then(Mono.defer(() -> unsolicitedResponses(session, 
responder, false)))
                 .then(Mono.fromRunnable(responder::flush));
         }
 


---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscr...@james.apache.org
For additional commands, e-mail: notifications-h...@james.apache.org

Reply via email to