You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by Ron Gomes <ro...@morganstanley.com> on 2004/06/24 15:07:41 UTC

Race condition in SystemLogHandler.java

I posted this in tomcat-user but it's probably more appropriate here.

---------- Forwarded message ----------
Date: Tue, 22 Jun 2004 16:16:36 -0400 (EDT)
From: Ron Gomes <ro...@morganstanley.com>
To: tomcat-user@jakarta.apache.org
Subject: Race condition in SystemLogHandler.java

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
observe).

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: tomcat-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: tomcat-dev-help@jakarta.apache.org