From 5299db3806c1bdb51b98d658daf558c4fa5e6c1d Mon Sep 17 00:00:00 2001 From: Phillip Webb Date: Sat, 24 Dec 2016 11:00:51 -0800 Subject: [PATCH] Fix deadlock when calling LiveReloadServer.stop() Update LiveReloadServer so that different synchronization blocks are used for the sockets and connection lists. Prior to this commit calling `LiveReloadServer.stop()` would always result in a 60 second delay since `stop()` owned the monitor add `removeConnection()` (called from a different thread) needs it to remove the active connection. Fixes gh-7749 --- .../devtools/livereload/LiveReloadServer.java | 20 ++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/livereload/LiveReloadServer.java b/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/livereload/LiveReloadServer.java index b4ed90b8f8..2475bb2e12 100644 --- a/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/livereload/LiveReloadServer.java +++ b/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/livereload/LiveReloadServer.java @@ -199,7 +199,7 @@ public class LiveReloadServer { } private void closeAllConnections() throws IOException { - synchronized (this.monitor) { + synchronized (this.connections) { for (Connection connection : this.connections) { connection.close(); } @@ -211,25 +211,27 @@ public class LiveReloadServer { */ public void triggerReload() { synchronized (this.monitor) { - for (Connection connection : this.connections) { - try { - connection.triggerReload(); - } - catch (Exception ex) { - logger.debug("Unable to send reload message", ex); + synchronized (this.connections) { + for (Connection connection : this.connections) { + try { + connection.triggerReload(); + } + catch (Exception ex) { + logger.debug("Unable to send reload message", ex); + } } } } } private void addConnection(Connection connection) { - synchronized (this.monitor) { + synchronized (this.connections) { this.connections.add(connection); } } private void removeConnection(Connection connection) { - synchronized (this.monitor) { + synchronized (this.connections) { this.connections.remove(connection); } }