I was hoping that 1.2 b1 would end up being the final release, but a co-worker (Jack Repenning) led me to a fairly serious leakage of the count of Worker objects used by XmlRpcServer. (I've committed fixes for this to the HEAD and XMLRPC_1_2_BRANCH.)

In light of this significant stability change, I'd like to formerly release 1.2 b2 (which I've created a tag for), which will hopefull end up tagged as the final release in the 1.2 series. Committers, may I have your votes please:

[ ] Yes, please proceed with the release (+1).
[ ] Don't have an opinion or won't block the release (+0)
[ ] No (-1), because: ____________________________________________

Thanks, Dan


[EMAIL PROTECTED] wrote:
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



Reply via email to