mirror of
https://github.com/openjdk/jdk.git
synced 2025-09-19 10:34:38 +02:00
8151264: Add a notification mechanism for UL configuration changes
Reviewed-by: dholmes, mlarsson
This commit is contained in:
parent
46da2cd7f3
commit
c75117cf29
4 changed files with 68 additions and 2 deletions
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -136,4 +136,27 @@ void Test_configure_stdout() {
|
||||||
LogConfiguration::parse_log_arguments("stdout", saved_config, NULL, NULL, log.error_stream());
|
LogConfiguration::parse_log_arguments("stdout", saved_config, NULL, NULL, log.error_stream());
|
||||||
os::free(saved_config);
|
os::free(saved_config);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int Test_logconfiguration_subscribe_triggered = 0;
|
||||||
|
|
||||||
|
static void Test_logconfiguration_subscribe_helper() {
|
||||||
|
Test_logconfiguration_subscribe_triggered++;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Test_logconfiguration_subscribe() {
|
||||||
|
ResourceMark rm;
|
||||||
|
LogHandle(logging) log;
|
||||||
|
|
||||||
|
LogConfiguration::register_update_listener(&Test_logconfiguration_subscribe_helper);
|
||||||
|
|
||||||
|
LogConfiguration::parse_log_arguments("stdout", "logging=trace", NULL, NULL, log.error_stream());
|
||||||
|
assert(Test_logconfiguration_subscribe_triggered == 1, "subscription not triggered (1)");
|
||||||
|
|
||||||
|
LogConfiguration::configure_stdout(LogLevel::Debug, true, LOG_TAGS(gc));
|
||||||
|
assert(Test_logconfiguration_subscribe_triggered == 2, "subscription not triggered (2)");
|
||||||
|
|
||||||
|
LogConfiguration::disable_logging();
|
||||||
|
assert(Test_logconfiguration_subscribe_triggered == 3, "subscription not triggered (3)");
|
||||||
|
}
|
||||||
|
|
||||||
#endif // PRODUCT
|
#endif // PRODUCT
|
||||||
|
|
|
@ -40,6 +40,9 @@
|
||||||
LogOutput** LogConfiguration::_outputs = NULL;
|
LogOutput** LogConfiguration::_outputs = NULL;
|
||||||
size_t LogConfiguration::_n_outputs = 0;
|
size_t LogConfiguration::_n_outputs = 0;
|
||||||
|
|
||||||
|
LogConfiguration::UpdateListenerFunction* LogConfiguration::_listener_callbacks = NULL;
|
||||||
|
size_t LogConfiguration::_n_listener_callbacks = 0;
|
||||||
|
|
||||||
// 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
|
||||||
// (when calling configure_output or reading/modifying the outputs array).
|
// (when calling configure_output or reading/modifying the outputs array).
|
||||||
|
@ -254,6 +257,7 @@ void LogConfiguration::disable_logging() {
|
||||||
for (size_t i = 0; i < _n_outputs; i++) {
|
for (size_t i = 0; i < _n_outputs; i++) {
|
||||||
disable_output(i);
|
disable_output(i);
|
||||||
}
|
}
|
||||||
|
notify_update_listeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
void LogConfiguration::configure_stdout(LogLevelType level, bool exact_match, ...) {
|
void LogConfiguration::configure_stdout(LogLevelType level, bool exact_match, ...) {
|
||||||
|
@ -282,6 +286,7 @@ void LogConfiguration::configure_stdout(LogLevelType level, bool exact_match, ..
|
||||||
// Apply configuration to stdout (output #0), with the same decorators as before.
|
// Apply configuration to stdout (output #0), with the same decorators as before.
|
||||||
ConfigurationLock cl;
|
ConfigurationLock cl;
|
||||||
configure_output(0, expr, LogOutput::Stdout->decorators());
|
configure_output(0, expr, LogOutput::Stdout->decorators());
|
||||||
|
notify_update_listeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool LogConfiguration::parse_command_line_arguments(const char* opts) {
|
bool LogConfiguration::parse_command_line_arguments(const char* opts) {
|
||||||
|
@ -373,6 +378,7 @@ bool LogConfiguration::parse_log_arguments(const char* outputstr,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
configure_output(idx, expr, decorators);
|
configure_output(idx, expr, decorators);
|
||||||
|
notify_update_listeners();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -471,3 +477,20 @@ void LogConfiguration::rotate_all_outputs() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void LogConfiguration::register_update_listener(UpdateListenerFunction cb) {
|
||||||
|
assert(cb != NULL, "Should not register NULL as listener");
|
||||||
|
ConfigurationLock cl;
|
||||||
|
size_t idx = _n_listener_callbacks++;
|
||||||
|
_listener_callbacks = REALLOC_C_HEAP_ARRAY(UpdateListenerFunction,
|
||||||
|
_listener_callbacks,
|
||||||
|
_n_listener_callbacks,
|
||||||
|
mtLogging);
|
||||||
|
_listener_callbacks[idx] = cb;
|
||||||
|
}
|
||||||
|
|
||||||
|
void LogConfiguration::notify_update_listeners() {
|
||||||
|
assert(ConfigurationLock::current_thread_has_lock(), "notify_update_listeners must be called in ConfigurationLock scope (lock held)");
|
||||||
|
for (size_t i = 0; i < _n_listener_callbacks; i++) {
|
||||||
|
_listener_callbacks[i]();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -37,10 +37,26 @@ class LogTagLevelExpression;
|
||||||
// kept implicitly in the LogTagSets and their LogOutputLists. During configuration the tagsets
|
// kept implicitly in the LogTagSets and their LogOutputLists. During configuration the tagsets
|
||||||
// are iterated over and updated accordingly.
|
// are iterated over and updated accordingly.
|
||||||
class LogConfiguration : public AllStatic {
|
class LogConfiguration : public AllStatic {
|
||||||
|
public:
|
||||||
|
// Function for listeners
|
||||||
|
typedef void (*UpdateListenerFunction)(void);
|
||||||
|
|
||||||
|
// Register callback for config change.
|
||||||
|
// The callback is always called with ConfigurationLock held,
|
||||||
|
// hence doing log reconfiguration from the callback will deadlock.
|
||||||
|
// The main Java thread may call this callback if there is an early registration
|
||||||
|
// else the attach listener JavaThread, started via diagnostic command, will be executing thread.
|
||||||
|
// The main purpose of this callback is to see if a loglevel have been changed.
|
||||||
|
// There is no way to unregister.
|
||||||
|
static void register_update_listener(UpdateListenerFunction cb);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static LogOutput** _outputs;
|
static LogOutput** _outputs;
|
||||||
static size_t _n_outputs;
|
static size_t _n_outputs;
|
||||||
|
|
||||||
|
static UpdateListenerFunction* _listener_callbacks;
|
||||||
|
static size_t _n_listener_callbacks;
|
||||||
|
|
||||||
// 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);
|
||||||
|
|
||||||
|
@ -60,6 +76,9 @@ class LogConfiguration : public AllStatic {
|
||||||
// Configure output (add or update existing configuration) to log on tag-level combination using specified decorators.
|
// Configure output (add or update existing configuration) to log on tag-level combination using specified decorators.
|
||||||
static void configure_output(size_t idx, const LogTagLevelExpression& tag_level_expression, const LogDecorators& decorators);
|
static void configure_output(size_t idx, const LogTagLevelExpression& tag_level_expression, const LogDecorators& decorators);
|
||||||
|
|
||||||
|
// This should be called after any configuration change while still holding ConfigurationLock
|
||||||
|
static void notify_update_listeners();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// Initialization and finalization of log configuration, to be run at vm startup and shutdown respectively.
|
// Initialization and finalization of log configuration, to be run at vm startup and shutdown respectively.
|
||||||
static void initialize(jlong vm_start_time);
|
static void initialize(jlong vm_start_time);
|
||||||
|
|
|
@ -69,6 +69,7 @@ void InternalVMTests::run() {
|
||||||
run_unit_test(JSON_test);
|
run_unit_test(JSON_test);
|
||||||
run_unit_test(Test_log_length);
|
run_unit_test(Test_log_length);
|
||||||
run_unit_test(Test_configure_stdout);
|
run_unit_test(Test_configure_stdout);
|
||||||
|
run_unit_test(Test_logconfiguration_subscribe);
|
||||||
run_unit_test(DirectivesParser_test);
|
run_unit_test(DirectivesParser_test);
|
||||||
run_unit_test(Test_TempNewSymbol);
|
run_unit_test(Test_TempNewSymbol);
|
||||||
#if INCLUDE_VM_STRUCTS
|
#if INCLUDE_VM_STRUCTS
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue