mirror of
https://github.com/openjdk/jdk.git
synced 2025-09-18 18:14:38 +02:00
8268638: semaphores of AsyncLogWriter may be broken when JVM is exiting.
Backport-of: fa3b44d438
This commit is contained in:
parent
8caeca003e
commit
b9d7337697
2 changed files with 15 additions and 16 deletions
|
@ -28,24 +28,18 @@
|
||||||
#include "logging/logHandle.hpp"
|
#include "logging/logHandle.hpp"
|
||||||
#include "runtime/atomic.hpp"
|
#include "runtime/atomic.hpp"
|
||||||
|
|
||||||
Semaphore AsyncLogWriter::_sem(0);
|
class AsyncLogWriter::AsyncLogLocker : public StackObj {
|
||||||
Semaphore AsyncLogWriter::_io_sem(1);
|
|
||||||
|
|
||||||
class AsyncLogLocker : public StackObj {
|
|
||||||
private:
|
|
||||||
static Semaphore _lock;
|
|
||||||
public:
|
public:
|
||||||
AsyncLogLocker() {
|
AsyncLogLocker() {
|
||||||
_lock.wait();
|
assert(_instance != nullptr, "AsyncLogWriter::_lock is unavailable");
|
||||||
|
_instance->_lock.wait();
|
||||||
}
|
}
|
||||||
|
|
||||||
~AsyncLogLocker() {
|
~AsyncLogLocker() {
|
||||||
_lock.signal();
|
_instance->_lock.signal();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
Semaphore AsyncLogLocker::_lock(1);
|
|
||||||
|
|
||||||
void AsyncLogWriter::enqueue_locked(const AsyncLogMessage& msg) {
|
void AsyncLogWriter::enqueue_locked(const AsyncLogMessage& msg) {
|
||||||
if (_buffer.size() >= _buffer_max_size) {
|
if (_buffer.size() >= _buffer_max_size) {
|
||||||
bool p_created;
|
bool p_created;
|
||||||
|
@ -64,7 +58,7 @@ void AsyncLogWriter::enqueue(LogFileOutput& output, const LogDecorations& decora
|
||||||
AsyncLogMessage m(output, decorations, os::strdup(msg));
|
AsyncLogMessage m(output, decorations, os::strdup(msg));
|
||||||
|
|
||||||
{ // critical area
|
{ // critical area
|
||||||
AsyncLogLocker lock;
|
AsyncLogLocker locker;
|
||||||
enqueue_locked(m);
|
enqueue_locked(m);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -72,7 +66,7 @@ void AsyncLogWriter::enqueue(LogFileOutput& output, const LogDecorations& decora
|
||||||
// LogMessageBuffer consists of a multiple-part/multiple-line messsage.
|
// LogMessageBuffer consists of a multiple-part/multiple-line messsage.
|
||||||
// The lock here guarantees its integrity.
|
// The lock here guarantees its integrity.
|
||||||
void AsyncLogWriter::enqueue(LogFileOutput& output, LogMessageBuffer::Iterator msg_iterator) {
|
void AsyncLogWriter::enqueue(LogFileOutput& output, LogMessageBuffer::Iterator msg_iterator) {
|
||||||
AsyncLogLocker lock;
|
AsyncLogLocker locker;
|
||||||
|
|
||||||
for (; !msg_iterator.is_at_end(); msg_iterator++) {
|
for (; !msg_iterator.is_at_end(); msg_iterator++) {
|
||||||
AsyncLogMessage m(output, msg_iterator.decorations(), os::strdup(msg_iterator.message()));
|
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()
|
AsyncLogWriter::AsyncLogWriter()
|
||||||
: _initialized(false),
|
: _lock(1), _sem(0), _io_sem(1),
|
||||||
|
_initialized(false),
|
||||||
_stats(17 /*table_size*/) {
|
_stats(17 /*table_size*/) {
|
||||||
if (os::create_thread(this, os::asynclog_thread)) {
|
if (os::create_thread(this, os::asynclog_thread)) {
|
||||||
_initialized = true;
|
_initialized = true;
|
||||||
|
@ -125,7 +120,7 @@ void AsyncLogWriter::write() {
|
||||||
bool own_io = false;
|
bool own_io = false;
|
||||||
|
|
||||||
{ // critical region
|
{ // critical region
|
||||||
AsyncLogLocker lock;
|
AsyncLogLocker locker;
|
||||||
|
|
||||||
_buffer.pop_all(&logs);
|
_buffer.pop_all(&logs);
|
||||||
// append meta-messages of dropped counters
|
// 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.
|
// times. It is no-op if async logging is not established.
|
||||||
//
|
//
|
||||||
class AsyncLogWriter : public NonJavaThread {
|
class AsyncLogWriter : public NonJavaThread {
|
||||||
|
class AsyncLogLocker;
|
||||||
|
|
||||||
static AsyncLogWriter* _instance;
|
static AsyncLogWriter* _instance;
|
||||||
|
// _lock(1) denotes a critional region.
|
||||||
|
Semaphore _lock;
|
||||||
// _sem is a semaphore whose value denotes how many messages have been enqueued.
|
// _sem is a semaphore whose value denotes how many messages have been enqueued.
|
||||||
// It decreases in AsyncLogWriter::run()
|
// It decreases in AsyncLogWriter::run()
|
||||||
static Semaphore _sem;
|
Semaphore _sem;
|
||||||
// A lock of IO
|
// A lock of IO
|
||||||
static Semaphore _io_sem;
|
Semaphore _io_sem;
|
||||||
|
|
||||||
volatile bool _initialized;
|
volatile bool _initialized;
|
||||||
AsyncLogMap _stats; // statistics for dropped messages
|
AsyncLogMap _stats; // statistics for dropped messages
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue