Skip to content

Commit b8c92ce

Browse files
committed
Consistent volatile access to running flag in Lifecycle implementations
Issue: SPR-16596 Issue: SPR-16488 (cherry picked from commit d4a8f76)
1 parent 6158634 commit b8c92ce

File tree

15 files changed

+76
-109
lines changed

15 files changed

+76
-109
lines changed

Diff for: spring-jms/src/main/java/org/springframework/jms/listener/AbstractJmsListeningContainer.java

+3-5
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2016 the original author or authors.
2+
* Copyright 2002-2018 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -76,7 +76,7 @@ public abstract class AbstractJmsListeningContainer extends JmsDestinationAccess
7676

7777
private boolean active = false;
7878

79-
private boolean running = false;
79+
private volatile boolean running = false;
8080

8181
private final List<Object> pausedTasks = new LinkedList<Object>();
8282

@@ -344,9 +344,7 @@ protected void doStop() throws JMSException {
344344
*/
345345
@Override
346346
public final boolean isRunning() {
347-
synchronized (this.lifecycleMonitor) {
348-
return (this.running && runningAllowed());
349-
}
347+
return (this.running && runningAllowed());
350348
}
351349

352350
/**

Diff for: spring-messaging/src/main/java/org/springframework/messaging/simp/annotation/support/SimpAnnotationMethodMessageHandler.java

+4-6
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2017 the original author or authors.
2+
* Copyright 2002-2018 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -111,10 +111,10 @@ public class SimpAnnotationMethodMessageHandler extends AbstractMethodMessageHan
111111

112112
private MessageHeaderInitializer headerInitializer;
113113

114-
private final Object lifecycleMonitor = new Object();
115-
116114
private volatile boolean running = false;
117115

116+
private final Object lifecycleMonitor = new Object();
117+
118118

119119
/**
120120
* Create an instance of SimpAnnotationMethodMessageHandler with the given
@@ -298,9 +298,7 @@ public final void stop(Runnable callback) {
298298

299299
@Override
300300
public final boolean isRunning() {
301-
synchronized (this.lifecycleMonitor) {
302-
return this.running;
303-
}
301+
return this.running;
304302
}
305303

306304

Diff for: spring-messaging/src/main/java/org/springframework/messaging/simp/broker/AbstractBrokerMessageHandler.java

+4-10
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2017 the original author or authors.
2+
* Copyright 2002-2018 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -153,9 +153,7 @@ public int getPhase() {
153153
@Override
154154
public void start() {
155155
synchronized (this.lifecycleMonitor) {
156-
if (logger.isInfoEnabled()) {
157-
logger.info("Starting...");
158-
}
156+
logger.info("Starting...");
159157
this.clientInboundChannel.subscribe(this);
160158
this.brokerChannel.subscribe(this);
161159
if (this.clientInboundChannel instanceof InterceptableChannel) {
@@ -173,9 +171,7 @@ protected void startInternal() {
173171
@Override
174172
public void stop() {
175173
synchronized (this.lifecycleMonitor) {
176-
if (logger.isInfoEnabled()) {
177-
logger.info("Stopping...");
178-
}
174+
logger.info("Stopping...");
179175
stopInternal();
180176
this.clientInboundChannel.unsubscribe(this);
181177
this.brokerChannel.unsubscribe(this);
@@ -206,9 +202,7 @@ public final void stop(Runnable callback) {
206202
*/
207203
@Override
208204
public final boolean isRunning() {
209-
synchronized (this.lifecycleMonitor) {
210-
return this.running;
211-
}
205+
return this.running;
212206
}
213207

214208
/**

Diff for: spring-messaging/src/main/java/org/springframework/messaging/simp/user/UserDestinationMessageHandler.java

+4-6
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2016 the original author or authors.
2+
* Copyright 2002-2018 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -64,10 +64,10 @@ public class UserDestinationMessageHandler implements MessageHandler, SmartLifec
6464

6565
private MessageHeaderInitializer headerInitializer;
6666

67-
private final Object lifecycleMonitor = new Object();
68-
6967
private volatile boolean running = false;
7068

69+
private final Object lifecycleMonitor = new Object();
70+
7171

7272
/**
7373
* Create an instance with the given client and broker channels subscribing
@@ -180,9 +180,7 @@ public final void stop(Runnable callback) {
180180

181181
@Override
182182
public final boolean isRunning() {
183-
synchronized (this.lifecycleMonitor) {
184-
return this.running;
185-
}
183+
return this.running;
186184
}
187185

188186

Diff for: spring-tx/src/main/java/org/springframework/jca/endpoint/GenericMessageEndpointManager.java

+3-5
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2016 the original author or authors.
2+
* Copyright 2002-2018 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -156,7 +156,7 @@ public class GenericMessageEndpointManager implements SmartLifecycle, Initializi
156156

157157
private int phase = Integer.MAX_VALUE;
158158

159-
private boolean running = false;
159+
private volatile boolean running = false;
160160

161161
private final Object lifecycleMonitor = new Object();
162162

@@ -318,9 +318,7 @@ public void stop(Runnable callback) {
318318
*/
319319
@Override
320320
public boolean isRunning() {
321-
synchronized (this.lifecycleMonitor) {
322-
return this.running;
323-
}
321+
return this.running;
324322
}
325323

326324
/**

Diff for: spring-websocket/src/main/java/org/springframework/web/socket/client/ConnectionManagerSupport.java

+4-7
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2016 the original author or authors.
2+
* Copyright 2002-2018 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -38,15 +38,14 @@ public abstract class ConnectionManagerSupport implements SmartLifecycle {
3838

3939
protected final Log logger = LogFactory.getLog(getClass());
4040

41-
4241
private final URI uri;
4342

4443
private boolean autoStartup = false;
4544

46-
private boolean running = false;
47-
4845
private int phase = Integer.MAX_VALUE;
4946

47+
private volatile boolean running = false;
48+
5049
private final Object lifecycleMonitor = new Object();
5150

5251

@@ -161,9 +160,7 @@ protected void stopInternal() throws Exception {
161160
*/
162161
@Override
163162
public boolean isRunning() {
164-
synchronized (this.lifecycleMonitor) {
165-
return this.running;
166-
}
163+
return this.running;
167164
}
168165

169166

Diff for: spring-websocket/src/main/java/org/springframework/web/socket/client/jetty/JettyWebSocketClient.java

+17-33
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2017 the original author or authors.
2+
* Copyright 2002-2018 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -60,8 +60,6 @@ public class JettyWebSocketClient extends AbstractWebSocketClient implements Lif
6060

6161
private final org.eclipse.jetty.websocket.client.WebSocketClient client;
6262

63-
private final Object lifecycleMonitor = new Object();
64-
6563
private AsyncListenableTaskExecutor taskExecutor = new SimpleAsyncTaskExecutor();
6664

6765

@@ -99,47 +97,33 @@ public AsyncListenableTaskExecutor getTaskExecutor() {
9997
return this.taskExecutor;
10098
}
10199

102-
@Override
103-
public boolean isRunning() {
104-
synchronized (this.lifecycleMonitor) {
105-
return this.client.isStarted();
106-
}
107-
}
108100

109101
@Override
110102
public void start() {
111-
synchronized (this.lifecycleMonitor) {
112-
if (!isRunning()) {
113-
try {
114-
if (logger.isInfoEnabled()) {
115-
logger.info("Starting Jetty WebSocketClient");
116-
}
117-
this.client.start();
118-
}
119-
catch (Exception ex) {
120-
throw new IllegalStateException("Failed to start Jetty client", ex);
121-
}
122-
}
103+
try {
104+
this.client.start();
105+
}
106+
catch (Exception ex) {
107+
throw new IllegalStateException("Failed to start Jetty WebSocketClient", ex);
123108
}
124109
}
125110

126111
@Override
127112
public void stop() {
128-
synchronized (this.lifecycleMonitor) {
129-
if (isRunning()) {
130-
try {
131-
if (logger.isInfoEnabled()) {
132-
logger.info("Stopping Jetty WebSocketClient");
133-
}
134-
this.client.stop();
135-
}
136-
catch (Exception ex) {
137-
logger.error("Error stopping Jetty WebSocketClient", ex);
138-
}
139-
}
113+
try {
114+
this.client.stop();
115+
}
116+
catch (Exception ex) {
117+
logger.error("Failed to stop Jetty WebSocketClient", ex);
140118
}
141119
}
142120

121+
@Override
122+
public boolean isRunning() {
123+
return this.client.isStarted();
124+
}
125+
126+
143127
@Override
144128
public ListenableFuture<WebSocketSession> doHandshake(WebSocketHandler webSocketHandler,
145129
String uriTemplate, Object... uriVars) {

Diff for: spring-websocket/src/main/java/org/springframework/web/socket/messaging/SubProtocolWebSocketHandler.java

+3-5
Original file line numberDiff line numberDiff line change
@@ -102,10 +102,10 @@ public class SubProtocolWebSocketHandler
102102

103103
private final Stats stats = new Stats();
104104

105-
private final Object lifecycleMonitor = new Object();
106-
107105
private volatile boolean running = false;
108106

107+
private final Object lifecycleMonitor = new Object();
108+
109109

110110
/**
111111
* Create a new {@code SubProtocolWebSocketHandler} for the given inbound and outbound channels.
@@ -279,9 +279,7 @@ public final void stop(Runnable callback) {
279279

280280
@Override
281281
public final boolean isRunning() {
282-
synchronized (this.lifecycleMonitor) {
283-
return this.running;
284-
}
282+
return this.running;
285283
}
286284

287285

Diff for: spring-websocket/src/main/java/org/springframework/web/socket/messaging/WebSocketStompClient.java

+3-4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2016 the original author or authors.
2+
* Copyright 2002-2018 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -72,17 +72,16 @@ public class WebSocketStompClient extends StompClientSupport implements SmartLif
7272

7373
private static final Log logger = LogFactory.getLog(WebSocketStompClient.class);
7474

75-
7675
private final WebSocketClient webSocketClient;
7776

7877
private int inboundMessageSizeLimit = 64 * 1024;
7978

8079
private boolean autoStartup = true;
8180

82-
private boolean running = false;
83-
8481
private int phase = Integer.MAX_VALUE;
8582

83+
private volatile boolean running = false;
84+
8685

8786
/**
8887
* Class constructor. Sets {@link #setDefaultHeartbeat} to "0,0" but will

Diff for: spring-websocket/src/main/java/org/springframework/web/socket/server/support/AbstractHandshakeHandler.java

+5-4
Original file line numberDiff line numberDiff line change
@@ -186,10 +186,6 @@ public String[] getSupportedProtocols() {
186186
return StringUtils.toStringArray(this.supportedProtocols);
187187
}
188188

189-
@Override
190-
public boolean isRunning() {
191-
return this.running;
192-
}
193189

194190
@Override
195191
public void start() {
@@ -219,6 +215,11 @@ protected void doStop() {
219215
}
220216
}
221217

218+
@Override
219+
public boolean isRunning() {
220+
return this.running;
221+
}
222+
222223

223224
@Override
224225
public final boolean doHandshake(ServerHttpRequest request, ServerHttpResponse response,

Diff for: spring-websocket/src/main/java/org/springframework/web/socket/server/support/WebSocketHttpRequestHandler.java

+6-6
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2015 the original author or authors.
2+
* Copyright 2002-2018 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -21,7 +21,6 @@
2121
import java.util.HashMap;
2222
import java.util.List;
2323
import java.util.Map;
24-
2524
import javax.servlet.ServletContext;
2625
import javax.servlet.ServletException;
2726
import javax.servlet.http.HttpServletRequest;
@@ -119,10 +118,6 @@ public void setServletContext(ServletContext servletContext) {
119118
}
120119
}
121120

122-
@Override
123-
public boolean isRunning() {
124-
return this.running;
125-
}
126121

127122
@Override
128123
public void start() {
@@ -144,6 +139,11 @@ public void stop() {
144139
}
145140
}
146141

142+
@Override
143+
public boolean isRunning() {
144+
return this.running;
145+
}
146+
147147

148148
@Override
149149
public void handleRequest(HttpServletRequest servletRequest, HttpServletResponse servletResponse)

0 commit comments

Comments
 (0)