mirror of
https://github.com/openjdk/jdk.git
synced 2025-09-17 01:24:33 +02:00
8145294: TestLogRotation.java triggers a race in the UL framework
Reviewed-by: sla, mgronlun
This commit is contained in:
parent
5e5def838e
commit
cc9cd893ac
5 changed files with 38 additions and 40 deletions
|
@ -39,7 +39,6 @@
|
||||||
|
|
||||||
LogOutput** LogConfiguration::_outputs = NULL;
|
LogOutput** LogConfiguration::_outputs = NULL;
|
||||||
size_t LogConfiguration::_n_outputs = 0;
|
size_t LogConfiguration::_n_outputs = 0;
|
||||||
bool LogConfiguration::_post_initialized = false;
|
|
||||||
|
|
||||||
// Stack object to take the lock for configuring the logging.
|
// Stack object to take the lock for configuring the logging.
|
||||||
// Should only be held during the critical parts of the configuration
|
// Should only be held during the critical parts of the configuration
|
||||||
|
@ -79,8 +78,6 @@ void LogConfiguration::post_initialize() {
|
||||||
ResourceMark rm;
|
ResourceMark rm;
|
||||||
describe(log.trace_stream());
|
describe(log.trace_stream());
|
||||||
}
|
}
|
||||||
|
|
||||||
_post_initialized = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void LogConfiguration::initialize(jlong vm_start_time) {
|
void LogConfiguration::initialize(jlong vm_start_time) {
|
||||||
|
@ -469,10 +466,9 @@ void LogConfiguration::print_command_line_help(FILE* out) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void LogConfiguration::rotate_all_outputs() {
|
void LogConfiguration::rotate_all_outputs() {
|
||||||
for (size_t idx = 0; idx < _n_outputs; idx++) {
|
// Start from index 2 since neither stdout nor stderr can be rotated.
|
||||||
if (_outputs[idx]->is_rotatable()) {
|
for (size_t idx = 2; idx < _n_outputs; idx++) {
|
||||||
_outputs[idx]->rotate(true);
|
_outputs[idx]->force_rotate();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -40,7 +40,6 @@ class LogConfiguration : public AllStatic {
|
||||||
private:
|
private:
|
||||||
static LogOutput** _outputs;
|
static LogOutput** _outputs;
|
||||||
static size_t _n_outputs;
|
static size_t _n_outputs;
|
||||||
static bool _post_initialized;
|
|
||||||
|
|
||||||
// Create a new output. Returns NULL if failed.
|
// Create a new output. Returns NULL if failed.
|
||||||
static LogOutput* new_output(char* name, const char* options, outputStream* errstream);
|
static LogOutput* new_output(char* name, const char* options, outputStream* errstream);
|
||||||
|
@ -96,10 +95,6 @@ class LogConfiguration : public AllStatic {
|
||||||
// Prints usage help for command line log configuration.
|
// Prints usage help for command line log configuration.
|
||||||
static void print_command_line_help(FILE* out);
|
static void print_command_line_help(FILE* out);
|
||||||
|
|
||||||
static bool is_post_initialized() {
|
|
||||||
return _post_initialized;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Rotates all LogOutput
|
// Rotates all LogOutput
|
||||||
static void rotate_all_outputs();
|
static void rotate_all_outputs();
|
||||||
};
|
};
|
||||||
|
|
|
@ -26,7 +26,6 @@
|
||||||
#include "logging/logConfiguration.hpp"
|
#include "logging/logConfiguration.hpp"
|
||||||
#include "logging/logFileOutput.hpp"
|
#include "logging/logFileOutput.hpp"
|
||||||
#include "memory/allocation.inline.hpp"
|
#include "memory/allocation.inline.hpp"
|
||||||
#include "runtime/mutexLocker.hpp"
|
|
||||||
#include "runtime/os.inline.hpp"
|
#include "runtime/os.inline.hpp"
|
||||||
#include "utilities/globalDefinitions.hpp"
|
#include "utilities/globalDefinitions.hpp"
|
||||||
#include "utilities/defaultStream.hpp"
|
#include "utilities/defaultStream.hpp"
|
||||||
|
@ -43,8 +42,7 @@ char LogFileOutput::_vm_start_time_str[StartTimeBufferSize];
|
||||||
LogFileOutput::LogFileOutput(const char* name)
|
LogFileOutput::LogFileOutput(const char* name)
|
||||||
: LogFileStreamOutput(NULL), _name(os::strdup_check_oom(name, mtLogging)),
|
: LogFileStreamOutput(NULL), _name(os::strdup_check_oom(name, mtLogging)),
|
||||||
_file_name(NULL), _archive_name(NULL), _archive_name_len(0), _current_size(0),
|
_file_name(NULL), _archive_name(NULL), _archive_name_len(0), _current_size(0),
|
||||||
_rotate_size(0), _current_file(1), _file_count(0),
|
_rotate_size(0), _current_file(1), _file_count(0), _rotation_semaphore(1) {
|
||||||
_rotation_lock(Mutex::leaf, "LogFileOutput rotation lock", true, Mutex::_safepoint_check_sometimes) {
|
|
||||||
_file_name = make_file_name(name, _pid_str, _vm_start_time_str);
|
_file_name = make_file_name(name, _pid_str, _vm_start_time_str);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -152,10 +150,15 @@ int LogFileOutput::write(const LogDecorations& decorations, const char* msg) {
|
||||||
// An error has occurred with this output, avoid writing to it.
|
// An error has occurred with this output, avoid writing to it.
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_rotation_semaphore.wait();
|
||||||
int written = LogFileStreamOutput::write(decorations, msg);
|
int written = LogFileStreamOutput::write(decorations, msg);
|
||||||
_current_size += written;
|
_current_size += written;
|
||||||
|
|
||||||
rotate(false);
|
if (should_rotate()) {
|
||||||
|
rotate();
|
||||||
|
}
|
||||||
|
_rotation_semaphore.signal();
|
||||||
|
|
||||||
return written;
|
return written;
|
||||||
}
|
}
|
||||||
|
@ -177,19 +180,28 @@ void LogFileOutput::archive() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void LogFileOutput::rotate(bool force) {
|
void LogFileOutput::force_rotate() {
|
||||||
|
if (_file_count == 0) {
|
||||||
if (!should_rotate(force)) {
|
// Rotation not possible
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
_rotation_semaphore.wait();
|
||||||
|
rotate();
|
||||||
|
_rotation_semaphore.signal();
|
||||||
|
}
|
||||||
|
|
||||||
MutexLockerEx ml(&_rotation_lock, true /* no safepoint check */);
|
void LogFileOutput::rotate() {
|
||||||
|
|
||||||
|
if (fclose(_stream)) {
|
||||||
|
jio_fprintf(defaultStream::error_stream(), "Error closing file '%s' during log rotation (%s).\n",
|
||||||
|
_file_name, strerror(errno));
|
||||||
|
}
|
||||||
|
|
||||||
// Archive the current log file
|
// Archive the current log file
|
||||||
archive();
|
archive();
|
||||||
|
|
||||||
// Open the active log file using the same stream as before
|
// Open the active log file using the same stream as before
|
||||||
_stream = freopen(_file_name, FileOpenMode, _stream);
|
_stream = fopen(_file_name, FileOpenMode);
|
||||||
if (_stream == NULL) {
|
if (_stream == NULL) {
|
||||||
jio_fprintf(defaultStream::error_stream(), "Could not reopen file '%s' during log rotation (%s).\n",
|
jio_fprintf(defaultStream::error_stream(), "Could not reopen file '%s' during log rotation (%s).\n",
|
||||||
_file_name, strerror(errno));
|
_file_name, strerror(errno));
|
||||||
|
|
|
@ -25,7 +25,7 @@
|
||||||
#define SHARE_VM_LOGGING_LOGFILEOUTPUT_HPP
|
#define SHARE_VM_LOGGING_LOGFILEOUTPUT_HPP
|
||||||
|
|
||||||
#include "logging/logFileStreamOutput.hpp"
|
#include "logging/logFileStreamOutput.hpp"
|
||||||
#include "runtime/mutex.hpp"
|
#include "runtime/semaphore.hpp"
|
||||||
#include "utilities/globalDefinitions.hpp"
|
#include "utilities/globalDefinitions.hpp"
|
||||||
|
|
||||||
class LogDecorations;
|
class LogDecorations;
|
||||||
|
@ -44,7 +44,6 @@ class LogFileOutput : public LogFileStreamOutput {
|
||||||
static char _pid_str[PidBufferSize];
|
static char _pid_str[PidBufferSize];
|
||||||
static char _vm_start_time_str[StartTimeBufferSize];
|
static char _vm_start_time_str[StartTimeBufferSize];
|
||||||
|
|
||||||
Mutex _rotation_lock;
|
|
||||||
const char* _name;
|
const char* _name;
|
||||||
char* _file_name;
|
char* _file_name;
|
||||||
char* _archive_name;
|
char* _archive_name;
|
||||||
|
@ -57,14 +56,17 @@ class LogFileOutput : public LogFileStreamOutput {
|
||||||
size_t _rotate_size;
|
size_t _rotate_size;
|
||||||
size_t _current_size;
|
size_t _current_size;
|
||||||
|
|
||||||
|
// Semaphore used for synchronizing file rotations and writes
|
||||||
|
Semaphore _rotation_semaphore;
|
||||||
|
|
||||||
void archive();
|
void archive();
|
||||||
|
void rotate();
|
||||||
bool configure_rotation(const char* options);
|
bool configure_rotation(const char* options);
|
||||||
char *make_file_name(const char* file_name, const char* pid_string, const char* timestamp_string);
|
char *make_file_name(const char* file_name, const char* pid_string, const char* timestamp_string);
|
||||||
static size_t parse_value(const char* value_str);
|
static size_t parse_value(const char* value_str);
|
||||||
|
|
||||||
bool should_rotate(bool force) {
|
bool should_rotate() {
|
||||||
return is_rotatable() &&
|
return _file_count > 0 && _rotate_size > 0 && _current_size >= _rotate_size;
|
||||||
(force || (_rotate_size > 0 && _current_size >= _rotate_size));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -72,12 +74,7 @@ class LogFileOutput : public LogFileStreamOutput {
|
||||||
virtual ~LogFileOutput();
|
virtual ~LogFileOutput();
|
||||||
virtual bool initialize(const char* options);
|
virtual bool initialize(const char* options);
|
||||||
virtual int write(const LogDecorations& decorations, const char* msg);
|
virtual int write(const LogDecorations& decorations, const char* msg);
|
||||||
|
virtual void force_rotate();
|
||||||
virtual bool is_rotatable() {
|
|
||||||
return LogConfiguration::is_post_initialized() && (_file_count > 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void rotate(bool force);
|
|
||||||
|
|
||||||
virtual const char* name() const {
|
virtual const char* name() const {
|
||||||
return _name;
|
return _name;
|
||||||
|
|
|
@ -75,17 +75,15 @@ class LogOutput : public CHeapObj<mtLogging> {
|
||||||
|
|
||||||
virtual ~LogOutput();
|
virtual ~LogOutput();
|
||||||
|
|
||||||
|
// If the output can be rotated, trigger a forced rotation, otherwise do nothing.
|
||||||
|
// Log outputs with rotation capabilities should override this.
|
||||||
|
virtual void force_rotate() {
|
||||||
|
// Do nothing by default.
|
||||||
|
}
|
||||||
|
|
||||||
virtual const char* name() const = 0;
|
virtual const char* name() const = 0;
|
||||||
virtual bool initialize(const char* options) = 0;
|
virtual bool initialize(const char* options) = 0;
|
||||||
virtual int write(const LogDecorations &decorations, const char* msg) = 0;
|
virtual int write(const LogDecorations &decorations, const char* msg) = 0;
|
||||||
|
|
||||||
virtual bool is_rotatable() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void rotate(bool force) {
|
|
||||||
// Do nothing by default.
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // SHARE_VM_LOGGING_LOGOUTPUT_HPP
|
#endif // SHARE_VM_LOGGING_LOGOUTPUT_HPP
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue