tomcat-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Ron Gomes <>
Subject Race condition in
Date Tue, 22 Jun 2004 20:16:36 GMT
The org.apache.tomcat.util.log.SystemLogHandler class (source code in
jakarta-tomcat-connectors-4.1.30) handles, among other things,
capturing of System.out and System.err so that they can be redirected
to an application's log file.  It makes use of another class
(CaptureLog) to hold the captured data, and maintains a stack of unused
CaptureLog instances to avoid creating new ones where possible.

This "reuse" stack is global to the class and it looks like the use of
it is not thread-safe.  The startCapture() method acquires a
CaptureLog() this way:

    if (!reuse.isEmpty()) {
	log = (CaptureLog)reuse.pop();
    } else {
	log = new CaptureLog();

There's a race between the call to isEmpty() and the call to pop().
We've been able to reliably elicit a java.util.EmptyStackException at
this point with an application under heavy load.

Replacing the above code with

    synchronized (reuse) {
	log = reuse.isEmpty() ? new CaptureLog() : (CaptureLog)reuse.pop();

eliminates the problem (with no effect on performance that we could

An alternative approach might be to catch the (rare)
EmptyStackException and treat it as equivalent to the isEmpty==true
case, but this seems cleaner.

There would seem to be no need to synchronize the code that pushes
old CaptureLog instances onto the reuse stack since java.util.Stack
is already synchronized.

To unsubscribe, e-mail:
For additional commands, e-mail:

View raw message