Skip to content
Permalink
Browse files
8268638: semaphores of AsyncLogWriter may be broken when JVM is exiting.
Reviewed-by: dholmes, phh
  • Loading branch information
Xin Liu authored and Paul Hohensee committed Jun 17, 2021
1 parent f2afe0a commit fa3b44d43811dca8c609d6c61a58680835abf8e3
Showing 2 changed files with 15 additions and 16 deletions.
@@ -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,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()));
@@ -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
@@ -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

0 comments on commit fa3b44d

Please sign in to comment.