From b9d7337697bd1aa5581b1a28efb3a78c221f6592 Mon Sep 17 00:00:00 2001 From: Xin Liu Date: Fri, 18 Jun 2021 21:29:55 +0000 Subject: [PATCH] 8268638: semaphores of AsyncLogWriter may be broken when JVM is exiting. Backport-of: fa3b44d43811dca8c609d6c61a58680835abf8e3 --- src/hotspot/share/logging/logAsyncWriter.cpp | 23 ++++++++------------ src/hotspot/share/logging/logAsyncWriter.hpp | 8 +++++-- 2 files changed, 15 insertions(+), 16 deletions(-) diff --git a/src/hotspot/share/logging/logAsyncWriter.cpp b/src/hotspot/share/logging/logAsyncWriter.cpp index b3b61f8a7c0..f46fc1c4ec8 100644 --- a/src/hotspot/share/logging/logAsyncWriter.cpp +++ b/src/hotspot/share/logging/logAsyncWriter.cpp @@ -28,24 +28,18 @@ #include "logging/logHandle.hpp" #include "runtime/atomic.hpp" -Semaphore AsyncLogWriter::_sem(0); -Semaphore AsyncLogWriter::_io_sem(1); - -class AsyncLogLocker : public StackObj { - private: - static Semaphore _lock; +class AsyncLogWriter::AsyncLogLocker : public StackObj { public: AsyncLogLocker() { - _lock.wait(); + assert(_instance != nullptr, "AsyncLogWriter::_lock is unavailable"); + _instance->_lock.wait(); } ~AsyncLogLocker() { - _lock.signal(); + _instance->_lock.signal(); } }; -Semaphore AsyncLogLocker::_lock(1); - void AsyncLogWriter::enqueue_locked(const AsyncLogMessage& msg) { if (_buffer.size() >= _buffer_max_size) { bool p_created; @@ -64,7 +58,7 @@ void AsyncLogWriter::enqueue(LogFileOutput& output, const LogDecorations& decora AsyncLogMessage m(output, decorations, os::strdup(msg)); { // critical area - AsyncLogLocker lock; + AsyncLogLocker locker; enqueue_locked(m); } } @@ -72,7 +66,7 @@ void AsyncLogWriter::enqueue(LogFileOutput& output, const LogDecorations& decora // LogMessageBuffer consists of a multiple-part/multiple-line messsage. // The lock here guarantees its integrity. void AsyncLogWriter::enqueue(LogFileOutput& output, LogMessageBuffer::Iterator msg_iterator) { - AsyncLogLocker lock; + AsyncLogLocker locker; for (; !msg_iterator.is_at_end(); msg_iterator++) { AsyncLogMessage m(output, msg_iterator.decorations(), os::strdup(msg_iterator.message())); @@ -81,7 +75,8 @@ void AsyncLogWriter::enqueue(LogFileOutput& output, LogMessageBuffer::Iterator m } AsyncLogWriter::AsyncLogWriter() - : _initialized(false), + : _lock(1), _sem(0), _io_sem(1), + _initialized(false), _stats(17 /*table_size*/) { if (os::create_thread(this, os::asynclog_thread)) { _initialized = true; @@ -125,7 +120,7 @@ void AsyncLogWriter::write() { bool own_io = false; { // critical region - AsyncLogLocker lock; + AsyncLogLocker locker; _buffer.pop_all(&logs); // append meta-messages of dropped counters diff --git a/src/hotspot/share/logging/logAsyncWriter.hpp b/src/hotspot/share/logging/logAsyncWriter.hpp index 736a957b218..23c92c5d8fd 100644 --- a/src/hotspot/share/logging/logAsyncWriter.hpp +++ b/src/hotspot/share/logging/logAsyncWriter.hpp @@ -133,12 +133,16 @@ typedef KVHashtable AsyncLogMap; // times. It is no-op if async logging is not established. // class AsyncLogWriter : public NonJavaThread { + class AsyncLogLocker; + static AsyncLogWriter* _instance; + // _lock(1) denotes a critional region. + Semaphore _lock; // _sem is a semaphore whose value denotes how many messages have been enqueued. // It decreases in AsyncLogWriter::run() - static Semaphore _sem; + Semaphore _sem; // A lock of IO - static Semaphore _io_sem; + Semaphore _io_sem; volatile bool _initialized; AsyncLogMap _stats; // statistics for dropped messages