Skip to content

Commit

Permalink
8268638: semaphores of AsyncLogWriter may be broken when JVM is exiting.
Browse files Browse the repository at this point in the history
Backport-of: fa3b44d
  • Loading branch information
Xin Liu authored and Paul Hohensee committed Jun 18, 2021
1 parent 8caeca0 commit b9d7337
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 16 deletions.
23 changes: 9 additions & 14 deletions src/hotspot/share/logging/logAsyncWriter.cpp
Expand Up @@ -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;
Expand All @@ -64,15 +58,15 @@ void AsyncLogWriter::enqueue(LogFileOutput& output, const LogDecorations& decora
AsyncLogMessage m(output, decorations, os::strdup(msg));

{ // critical area
AsyncLogLocker lock;
AsyncLogLocker locker;
enqueue_locked(m);
}
}

// 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()));
Expand All @@ -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;
Expand Down Expand Up @@ -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
Expand Down
8 changes: 6 additions & 2 deletions src/hotspot/share/logging/logAsyncWriter.hpp
Expand Up @@ -133,12 +133,16 @@ typedef KVHashtable<LogFileOutput*, uint32_t, mtLogging> 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
Expand Down

0 comments on commit b9d7337

Please sign in to comment.