dlr 2004/04/30 17:39:05
Modified: src/java/org/apache/xmlrpc Tag: XMLRPC_1_2_BRANCH XmlRpcServer.java WebServer.java Log: Corrected a leak in XmlRpcServer's worker count, and normalized concurrency maximums on XmlRpc.getMaxThreads(). * src/java/org/apache/xmlrpc/XmlRpcServer.java execute(InputStream, XmlRpcContext): Fix the possibility of inaccurate tracking of the worker count which can be caused by a XmlRpcWorker's execute() method throwing a AuthenticationFailed, ParseFailed, or java.lang.Error. Use a try/finally block to assure that this leak condition is avoided, and that the worker count accurately reflects the number of available workers. getWorker(): Added JavaDoc. Improved error message. * src/java/org/apache/xmlrpc/WebServer.java getRunner(): Use the XmlRpc.getMaxThreads() method for the maximum number of Runner instances, rather than a hardcoded value of 255. Improved error message. repoolRunner(Runner): Renamed from releaseRunner(), and JavaDoc'd. Runner.handle(Socket): Added inline comment doc'ing reason for the call to "this.notify()". Runner.run(): Added inline comment doc'ing the reason for the "count" and "threadpool.size()" checks. Updated method name for repoolRunner(). Connection.run(): Remove duplicate error output when XmlRpc.debug is true. Issue: CollabNet PCN27955 Submitted by: Daniel Ral and Jack Repenning Revision Changes Path No revision No revision 1.35.2.1 +14 -5 ws-xmlrpc/src/java/org/apache/xmlrpc/XmlRpcServer.java Index: XmlRpcServer.java =================================================================== RCS file: /home/cvs/ws-xmlrpc/src/java/org/apache/xmlrpc/XmlRpcServer.java,v retrieving revision 1.35 retrieving revision 1.35.2.1 diff -u -u -r1.35 -r1.35.2.1 --- XmlRpcServer.java 21 Oct 2002 13:08:50 -0000 1.35 +++ XmlRpcServer.java 1 May 2004 00:39:04 -0000 1.35.2.1 @@ -148,15 +148,22 @@ public byte[] execute(InputStream is, XmlRpcContext context) { XmlRpcWorker worker = getWorker(); - byte[] retval = worker.execute(is, context); - pool.push(worker); - return retval; + try + { + return worker.execute(is, context); + } + finally + { + pool.push(worker); + } } /** * Hands out pooled workers. * - * @return A worker. + * @return A worker (never <code>null</code>). + * @throws RuntimeException If the server exceeds its maximum + * number of allowed requests. */ protected XmlRpcWorker getWorker() { @@ -176,7 +183,9 @@ } return createWorker(); } - throw new RuntimeException("System overload"); + throw new RuntimeException("System overload: Maximum number of " + + "concurrent requests (" + maxThreads + + ") exceeded"); } } 1.22.2.1 +16 -6 ws-xmlrpc/src/java/org/apache/xmlrpc/WebServer.java Index: WebServer.java =================================================================== RCS file: /home/cvs/ws-xmlrpc/src/java/org/apache/xmlrpc/WebServer.java,v retrieving revision 1.22 retrieving revision 1.22.2.1 diff -u -u -r1.22 -r1.22.2.1 --- WebServer.java 3 Dec 2002 17:22:26 -0000 1.22 +++ WebServer.java 1 May 2004 00:39:05 -0000 1.22.2.1 @@ -600,19 +600,23 @@ } catch (EmptyStackException empty) { - if (runners.activeCount () > 255) + int maxRequests = XmlRpc.getMaxThreads(); + if (runners.activeCount() > XmlRpc.getMaxThreads()) { - throw new RuntimeException("System overload"); + throw new RuntimeException("System overload: Maximum number " + + "of concurrent requests (" + + maxRequests + ") exceeded"); } return new Runner(); } } /** + * Put <code>runner</code> back into [EMAIL PROTECTED] #threadpool}. * - * @param runner + * @param runner The instance to reclaim. */ - void releaseRunner(Runner runner) + void repoolRunner(Runner runner) { threadpool.push(runner); } @@ -642,6 +646,7 @@ } else { + // Wake the thread waiting in our run() method. this.notify(); } } @@ -659,11 +664,13 @@ if (count > 200 || threadpool.size() > 20) { + // We're old, or the number of threads in the pool + // is large. return; } synchronized(this) { - releaseRunner(this); + repoolRunner(this); try { this.wait(); @@ -790,10 +797,13 @@ } catch (Exception exception) { - System.err.println(exception); if (XmlRpc.debug) { exception.printStackTrace(); + } + else + { + System.err.println(exception); } } finally