Sorry, it looks like this commit broke the build.

Failed tests:
  XmlCompactFileAppenderTest.testFlushAtEndOfBatch:60 line1
  XmlCompleteFileAppenderTest.testFlushAtEndOfBatch:67 line1
  XmlFileAppenderTest.testFlushAtEndOfBatch:65 line1

I'm working on this. As a stopgap solution I will temporarily mark these
tests as @Ignore.


On Sun, Jun 15, 2014 at 1:39 AM, <rpo...@apache.org> wrote:

> Author: rpopma
> Date: Sat Jun 14 16:39:11 2014
> New Revision: 1602598
>
> URL: http://svn.apache.org/r1602598
> Log:
> LOG4J2-392: fixed problem in previous solution that resulted in incorrect
> ref count in AsyncLoggerConfigHelper which caused premature shutdown of the
> shared Disruptor
>
> Modified:
>
> logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/config/AbstractConfiguration.java
>
> Modified:
> logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/config/AbstractConfiguration.java
> URL:
> http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/config/AbstractConfiguration.java?rev=1602598&r1=1602597&r2=1602598&view=diff
>
> ==============================================================================
> ---
> logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/config/AbstractConfiguration.java
> (original)
> +++
> logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/config/AbstractConfiguration.java
> Sat Jun 14 16:39:11 2014
> @@ -22,8 +22,10 @@ import java.io.InputStream;
>  import java.io.Serializable;
>  import java.util.Collection;
>  import java.util.Collections;
> +import java.util.HashSet;
>  import java.util.List;
>  import java.util.Map;
> +import java.util.Set;
>  import java.util.concurrent.ConcurrentHashMap;
>  import java.util.concurrent.ConcurrentMap;
>  import java.util.concurrent.CopyOnWriteArrayList;
> @@ -181,6 +183,7 @@ public abstract class AbstractConfigurat
>              }
>          }
>          // similarly, first stop AsyncLoggerConfig Disruptor thread(s)
> +        Set<LoggerConfig> alreadyStopped = new HashSet<LoggerConfig>();
>          int asyncLoggerConfigCount = 0;
>          for (final LoggerConfig logger : loggers.values()) {
>              if (logger instanceof AsyncLoggerConfig) {
> @@ -191,11 +194,13 @@ public abstract class AbstractConfigurat
>                  // Only *after this* the appenders can be cleared or
> events will be lost.
>                  logger.stop();
>                  asyncLoggerConfigCount++;
> +                alreadyStopped.add(logger);
>              }
>          }
>          if (root instanceof AsyncLoggerConfig) {
>              root.stop();
>              asyncLoggerConfigCount++;
> +            alreadyStopped.add(root);
>          }
>          LOGGER.trace("AbstractConfiguration stopped {}
> AsyncLoggerConfigs.", asyncLoggerConfigCount);
>
> @@ -223,15 +228,26 @@ public abstract class AbstractConfigurat
>
>          int loggerCount = 0;
>          for (final LoggerConfig logger : loggers.values()) {
> -            // AsyncLoggerConfig objects may be stopped multiple times,
> that's okay...
> +            // clear appenders, even if this logger is already stopped.
>              logger.clearAppenders();
> +
> +            // AsyncLoggerConfigHelper decreases its ref count when an
> AsyncLoggerConfig is stopped.
> +            // Stopping the same AsyncLoggerConfig twice results in an
> incorrect ref count and
> +            // the shared Disruptor may be shut down prematurely,
> resulting in NPE or other errors.
> +            if (alreadyStopped.contains(logger)) {
> +                continue;
> +            }
>              logger.stop();
>              loggerCount++;
>          }
>          LOGGER.trace("AbstractConfiguration stopped {} Loggers.",
> loggerCount);
>
> -        // If root is an AsyncLoggerConfig it may already be stopped.
> Stopping it twice is okay.
> -        root.stop();
> +        // AsyncLoggerConfigHelper decreases its ref count when an
> AsyncLoggerConfig is stopped.
> +        // Stopping the same AsyncLoggerConfig twice results in an
> incorrect ref count and
> +        // the shared Disruptor may be shut down prematurely, resulting
> in NPE or other errors.
> +        if (!alreadyStopped.contains(root)) {
> +            root.stop();
> +        }
>          super.stop();
>          if (advertiser != null && advertisement != null) {
>              advertiser.unadvertise(advertisement);
>
>
>

Reply via email to