There are a few corner-cases when logging with asynchronous UL, all of which should be fixed.
- If the AsyncLogWriter produces a log message, then it'll deadlock as it'll wait for itself to release the AsyncLogLock.
- If a producing thread produces another log message while enqueueing, then a deadlock will occur
We can fix this by keeping a thread as the owner of the lock. If the lock is owned by the current thread, then the thread resorts to synchronous logging.
Note, this fix introduces a third case:
- If an unattached thread logs then there is no identity, so we cannot check if it holds the lock. We must therefore resort to synchronous logging in this case also
In UL, we have so far guaranteed Program-Order log message appearance. In other words, log("A"); log("B"); is guaranteed to always appear in the order AB in the log output. For cases 1 and 3, we still keep this guarantee. However, for case 2 this guarantee is broken. The recursive log message will appear before any unflushed log messages from the logging thread. As I see no simple way of fixing this, along with the fact that this is highly unlikely to ever occur (this has never been observed in production), I think it's best to break that guarantee and prioritize logs not being missing.
As it's preferable that we do not have recursive logging (as in case 2 and partially in case 1),we can assert that these should not hold. In production systems we will handle the "bad" case correctly, as to not reach the aforementioned deadlock state.
- If the AsyncLogWriter produces a log message, then it'll deadlock as it'll wait for itself to release the AsyncLogLock.
- If a producing thread produces another log message while enqueueing, then a deadlock will occur
We can fix this by keeping a thread as the owner of the lock. If the lock is owned by the current thread, then the thread resorts to synchronous logging.
Note, this fix introduces a third case:
- If an unattached thread logs then there is no identity, so we cannot check if it holds the lock. We must therefore resort to synchronous logging in this case also
In UL, we have so far guaranteed Program-Order log message appearance. In other words, log("A"); log("B"); is guaranteed to always appear in the order AB in the log output. For cases 1 and 3, we still keep this guarantee. However, for case 2 this guarantee is broken. The recursive log message will appear before any unflushed log messages from the logging thread. As I see no simple way of fixing this, along with the fact that this is highly unlikely to ever occur (this has never been observed in production), I think it's best to break that guarantee and prioritize logs not being missing.
As it's preferable that we do not have recursive logging (as in case 2 and partially in case 1),we can assert that these should not hold. In production systems we will handle the "bad" case correctly, as to not reach the aforementioned deadlock state.
- causes
-
JDK-8350214 Test gtest/AsyncLogGtest.java fails after JDK-8349755
-
- Resolved
-
- links to
-
Commit(master) openjdk/jdk/f1258f9e
-
Review(master) openjdk/jdk/23513