mirror of
https://github.com/apache/maven-mvnd.git
synced 2025-09-10 21:22:03 +00:00
Fix daemon connection race condition (#1078)
The Server was using a SynchrnousQueue to coordinate the main thread and the background thread that receives the request from the client. A SynchronousQueue only allows insertions when a corresponding call to `get` is in progress. However, since the receiver thread is started before the call to `get`, there was a short time window, where the call to `queue.offer` could fail and simply return `false`. This return code was ignored. A possible solution would have been to call `put` instead of `offer`, but I decided to replace the queue with a Future, since we only wait for a single element. Co-authored-by: Stefan Oehme <st.oehme@gmail.com>
This commit is contained in:
@@ -37,11 +37,11 @@ import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.BlockingQueue;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.LinkedBlockingDeque;
|
||||
import java.util.concurrent.PriorityBlockingQueue;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.SynchronousQueue;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.locks.Condition;
|
||||
import java.util.concurrent.locks.Lock;
|
||||
@@ -271,13 +271,13 @@ public class Server implements AutoCloseable, Runnable {
|
||||
|
||||
try (DaemonConnection connection = new DaemonConnection(socket)) {
|
||||
LOGGER.info("Waiting for request");
|
||||
SynchronousQueue<Message> request = new SynchronousQueue<>();
|
||||
CompletableFuture<Message> request = new CompletableFuture<>();
|
||||
new DaemonThread(() -> {
|
||||
Message message = connection.receive();
|
||||
request.offer(message);
|
||||
request.complete(message);
|
||||
})
|
||||
.start();
|
||||
Message message = request.poll(1, TimeUnit.MINUTES);
|
||||
Message message = request.get(1, TimeUnit.MINUTES);
|
||||
if (message == null) {
|
||||
LOGGER.info("Could not receive request after one minute, dropping connection");
|
||||
updateState(DaemonState.Idle);
|
||||
|
Reference in New Issue
Block a user