You are viewing a plain text version of this content. The canonical link for it is here.
Posted to log4j-dev@logging.apache.org by "Robert Schaft (JIRA)" <ji...@apache.org> on 2015/06/10 15:47:00 UTC
[jira] [Created] (LOG4J2-1049) AsyncAppender eats my Interrupt
Robert Schaft created LOG4J2-1049:
-------------------------------------
Summary: AsyncAppender eats my Interrupt
Key: LOG4J2-1049
URL: https://issues.apache.org/jira/browse/LOG4J2-1049
Project: Log4j 2
Issue Type: Bug
Components: Appenders
Affects Versions: 2.3, 2.2
Environment: Java 7, Windows
Reporter: Robert Schaft
I wrote a LoggingThread that will be stopped by sending loggingThread.interrupt() from another Thread.
{code:title=LoggingThread.java}
class LoggingThread extends Thread {
private final static Logger LOGGER = LoggerFactory.getLogger(LoggingThread .class);
public void run() {
while (!Thread.currentThread().isInterrupted()) {
LOGGER.debug("{} is logging {}", this, "nothing");
}
}
}
{code}
Unfortunately, loggingThread.interrupt() is sometimes set before AsyncAppender.append() or at the beginning of that.
{code:title=AsyncAppender#append() line 153}
try {
// wait for free slots in the queue
queue.put(Log4jLogEvent.serialize(coreEvent, includeLocation));
appendSuccessful = true;
} catch (final InterruptedException e) {
LOGGER.warn("Interrupted while waiting for a free slot in the AsyncAppender LogEvent-queue {}",
getName());
}
{code}
This will make queue.put throw an InterruptedException and remove the interrupted flag of the current flag.
I suggest a simple bugfix: Call Thread by Thread.currentThread().interrupt() in the catch clause. This will reset the interrupted flag of the current Thread.
A more complex bugfix which doesn't loose a message:
{code:title=AsyncAppender#append() line 153}
Serializable serialized = Log4jLogEvent.serialize(coreEvent, includeLocation);
try {
// wait for free slots in the queue
queue.put(serialized);
appendSuccessful = true;
} catch (final InterruptedException e) {
try {
// The interrupt is catched and the interrupted flag is unset.
// Therefore offer() won't return with an InterruptedException
// unless another Thread sends again an interrupt.
// Use a timeout to handle the case where the Interrupt e
// was really meant for a hanging put() and not just
// coincidently sent at the same time.
// If the put() was really hanging,
// offer() would return with false after 10ms and no second
// external interrupt() is required
appendSuccessful = queue.offer(serialized, 10L, TimeUnit.MILLISECONDS);
} catch (final InterruptedException e2) {
// queue.put is really hanging and someone
}
if (!appendSuccessful) {
LOGGER.warn("Interrupted while waiting for a free slot in the AsyncAppender LogEvent-queue {}",
getName());
}
// set the interrupted flag again.
Thread.currentThread().interrupt();
}
{code}
--
This message was sent by Atlassian JIRA
(v6.3.4#6332)
---------------------------------------------------------------------
To unsubscribe, e-mail: log4j-dev-unsubscribe@logging.apache.org
For additional commands, e-mail: log4j-dev-help@logging.apache.org