Author: markt
Date: Wed Sep 3 13:36:43 2014
New Revision: 1622251
URL: http://svn.apache.org/r1622251
Log:
Fix https://issues.apache.org/bugzilla/show_bug.cgi?id=56905
Make destruction on web application stop of thread group used for WebSocket
connections more robust.
Patch by kkolinko with minor tweaks
Modified:
tomcat/trunk/java/org/apache/tomcat/websocket/server/LocalStrings.properties
tomcat/trunk/java/org/apache/tomcat/websocket/server/WsServerContainer.java
tomcat/trunk/webapps/docs/changelog.xml
Modified:
tomcat/trunk/java/org/apache/tomcat/websocket/server/LocalStrings.properties
URL:
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/websocket/server/LocalStrings.properties?rev=1622251&r1=1622250&r2=1622251&view=diff
==============================================================================
---
tomcat/trunk/java/org/apache/tomcat/websocket/server/LocalStrings.properties
(original)
+++
tomcat/trunk/java/org/apache/tomcat/websocket/server/LocalStrings.properties
Wed Sep 3 13:36:43 2014
@@ -22,7 +22,7 @@ serverContainer.missingEndpoint=An Endpo
serverContainer.pojoDeploy=POJO class [{0}] deploying to path [{1}] in
ServletContext [{2}]
serverContainer.servletContextMismatch=Attempted to register a POJO annotated
for WebSocket at path [{0}] in the ServletContext with context path [{1}] when
the WebSocket ServerContainer is allocated to the ServletContext with context
path [{2}]
serverContainer.servletContextMissing=No ServletContext was specified
-serverContainer.threadGroupNotDestroyed=Unable to destroy WebSocket thread
group [{0}] as some threads were still running when the web application was
stopped
+serverContainer.threadGroupNotDestroyed=Unable to destroy WebSocket thread
group [{0}] as [{1}] threads were still running when the web application was
stopped. The thread group will be destroyed once the threads terminate.
uriTemplate.duplicateParameter=The parameter [{0}] appears more than once in
the path which is not permitted
uriTemplate.emptySegment=The path [{0}] contains one or more empty segments
which are is not permitted
Modified:
tomcat/trunk/java/org/apache/tomcat/websocket/server/WsServerContainer.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/websocket/server/WsServerContainer.java?rev=1622251&r1=1622250&r2=1622251&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/websocket/server/WsServerContainer.java
(original)
+++ tomcat/trunk/java/org/apache/tomcat/websocket/server/WsServerContainer.java
Wed Sep 3 13:36:43 2014
@@ -273,14 +273,42 @@ public class WsServerContainer extends W
public void destroy() {
shutdownExecutor();
super.destroy();
+ // If the executor hasn't fully shutdown it won't be possible to
+ // destroy this thread group as there will still be threads running.
+ // Mark the thread group as daemon one, so that it destroys itself
+ // when thread count reaches zero.
+ // Synchronization on threadGroup is needed, as there is a race between
+ // destroy() call from termination of the last thread in thread group
+ // marked as daemon versus the explicit destroy() call.
+ int threadCount = threadGroup.activeCount();
+ boolean success = false;
try {
- threadGroup.destroy();
- } catch (IllegalThreadStateException itse) {
- // If the executor hasn't fully shutdown it won't be possible to
- // destroy this thread group as there will still be threads running
- log.warn(sm.getString("serverContainer.threadGroupNotDestroyed",
- threadGroup.getName()));
+ while (true) {
+ int oldThreadCount = threadCount;
+ synchronized (threadGroup) {
+ if (threadCount > 0) {
+ Thread.yield();
+ threadCount = threadGroup.activeCount();
+ }
+ if (threadCount > 0 && threadCount != oldThreadCount) {
+ // Value not stabilized. Retry.
+ continue;
+ }
+ if (threadCount > 0) {
+ threadGroup.setDaemon(true);
+ } else {
+ threadGroup.destroy();
+ success = true;
+ }
+ break;
+ }
+ }
+ } catch (IllegalThreadStateException exception) {
+ // Fall-through
}
+ if (!success) {
+ log.warn(sm.getString("serverContainer.threadGroupNotDestroyed",
+ threadGroup.getName(), Integer.valueOf(threadCount)));
}
}
Modified: tomcat/trunk/webapps/docs/changelog.xml
URL:
http://svn.apache.org/viewvc/tomcat/trunk/webapps/docs/changelog.xml?rev=1622251&r1=1622250&r2=1622251&view=diff
==============================================================================
--- tomcat/trunk/webapps/docs/changelog.xml (original)
+++ tomcat/trunk/webapps/docs/changelog.xml Wed Sep 3 13:36:43 2014
@@ -115,6 +115,10 @@
<subsection name="WebSocket">
<changelog>
<fix>
+ <bug>56905</bug>: Make destruction on web application stop of thread
+ group used for WebSocket connections more robust. (kkolinko/markt)
+ </fix>
+ <fix>
<bug>56907</bug>: Ensure that client IO threads are stopped if a secure
WebSocket client connection fails. (markt)
</fix>
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]