Author: bodewig Date: Thu Jun 19 05:20:12 2008 New Revision: 669464 URL: http://svn.apache.org/viewvc?rev=669464&view=rev Log: Remove synchronization around logging of messages in order to avoid potential deadlock - see PR 45194
Modified: ant/core/trunk/WHATSNEW ant/core/trunk/docs/manual/develop.html ant/core/trunk/src/main/org/apache/tools/ant/NoBannerLogger.java ant/core/trunk/src/main/org/apache/tools/ant/Project.java ant/core/trunk/src/main/org/apache/tools/ant/listener/Log4jListener.java Modified: ant/core/trunk/WHATSNEW URL: http://svn.apache.org/viewvc/ant/core/trunk/WHATSNEW?rev=669464&r1=669463&r2=669464&view=diff ============================================================================== --- ant/core/trunk/WHATSNEW (original) +++ ant/core/trunk/WHATSNEW Thu Jun 19 05:20:12 2008 @@ -38,6 +38,12 @@ to do so however using a new parameter. Bugzilla report 33969. +* A lock in Project ensured that a BuildListener's messageLogged + method was only ever executed by a single thread at a time, while + all other methods could be invoked by multiple threads + simultaniously (while within <parallel>, for example). This lock is + no longer in place, messageLogged should be made thread-safe now. + Fixed bugs: ----------- @@ -63,6 +69,10 @@ characters in them. Bugzilla report 45190 + * A deadlock could occur if a BuildListener tried to access an Ant property + within messageLogged while a different thread also accessed one. + Bugzilla report 45194 + Other changes: -------------- Modified: ant/core/trunk/docs/manual/develop.html URL: http://svn.apache.org/viewvc/ant/core/trunk/docs/manual/develop.html?rev=669464&r1=669463&r2=669464&view=diff ============================================================================== --- ant/core/trunk/docs/manual/develop.html (original) +++ ant/core/trunk/docs/manual/develop.html Thu Jun 19 05:20:12 2008 @@ -498,6 +498,11 @@ been configured. </p> +<p><b>Note2:</b> All methods of a BuildListener except for the "Build + Started" and "Build Finished" events may occur on several threads + simultaneously - for example while Ant is executing + a <code><parallel></code> task.</p> + <hr> <h2><a name="integration">Source code integration</a></h2> Modified: ant/core/trunk/src/main/org/apache/tools/ant/NoBannerLogger.java URL: http://svn.apache.org/viewvc/ant/core/trunk/src/main/org/apache/tools/ant/NoBannerLogger.java?rev=669464&r1=669463&r2=669464&view=diff ============================================================================== --- ant/core/trunk/src/main/org/apache/tools/ant/NoBannerLogger.java (original) +++ ant/core/trunk/src/main/org/apache/tools/ant/NoBannerLogger.java Thu Jun 19 05:20:12 2008 @@ -48,7 +48,7 @@ * @param event A BuildEvent containing target information. * Must not be <code>null</code>. */ - public void targetStarted(BuildEvent event) { + public synchronized void targetStarted(BuildEvent event) { targetName = extractTargetName(event); } @@ -67,7 +67,7 @@ * * @param event Ignored in this implementation. */ - public void targetFinished(BuildEvent event) { + public synchronized void targetFinished(BuildEvent event) { targetName = null; } @@ -88,9 +88,11 @@ return; } - if (null != targetName) { - out.println(StringUtils.LINE_SEP + targetName + ":"); - targetName = null; + synchronized (this) { + if (null != targetName) { + out.println(StringUtils.LINE_SEP + targetName + ":"); + targetName = null; + } } super.messageLogged(event); Modified: ant/core/trunk/src/main/org/apache/tools/ant/Project.java URL: http://svn.apache.org/viewvc/ant/core/trunk/src/main/org/apache/tools/ant/Project.java?rev=669464&r1=669463&r2=669464&view=diff ============================================================================== --- ant/core/trunk/src/main/org/apache/tools/ant/Project.java (original) +++ ant/core/trunk/src/main/org/apache/tools/ant/Project.java Thu Jun 19 05:20:12 2008 @@ -172,6 +172,14 @@ /** List of listeners to notify of build events. */ private Vector listeners = new Vector(); + /** for each thread, record whether it is currently executing + messageLogged */ + private final ThreadLocal isLoggingMessage = new ThreadLocal() { + protected Object initialValue() { + return Boolean.FALSE; + } + }; + /** * The Ant core classloader--may be <code>null</code> if using * parent classloader. @@ -202,11 +210,6 @@ private boolean keepGoingMode = false; /** - * Flag which catches Listeners which try to use System.out or System.err . - */ - private boolean loggingMessage = false; - - /** * Set the input handler. * * @param handler the InputHandler instance to use for gathering input. @@ -2144,8 +2147,7 @@ } else { event.setMessage(message, priority); } - synchronized (this) { - if (loggingMessage) { + if (isLoggingMessage.get() != Boolean.FALSE) { /* * One of the Listeners has attempted to access * System.err or System.out. @@ -2162,16 +2164,15 @@ return; } try { - loggingMessage = true; + isLoggingMessage.set(Boolean.TRUE); Iterator iter = listeners.iterator(); while (iter.hasNext()) { BuildListener listener = (BuildListener) iter.next(); listener.messageLogged(event); } } finally { - loggingMessage = false; + isLoggingMessage.set(Boolean.FALSE); } - } } /** Modified: ant/core/trunk/src/main/org/apache/tools/ant/listener/Log4jListener.java URL: http://svn.apache.org/viewvc/ant/core/trunk/src/main/org/apache/tools/ant/listener/Log4jListener.java?rev=669464&r1=669463&r2=669464&view=diff ============================================================================== --- ant/core/trunk/src/main/org/apache/tools/ant/listener/Log4jListener.java (original) +++ ant/core/trunk/src/main/org/apache/tools/ant/listener/Log4jListener.java Thu Jun 19 05:20:12 2008 @@ -34,7 +34,7 @@ public class Log4jListener implements BuildListener { /** Indicates if the listener was initialized. */ - private boolean initialized = false; + private final boolean initialized; /** * log category we log into