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