RFR: 8023168 - Cleanup LogManager class initialization and LogManager/LoggerContext relationship
Peter Levart
peter.levart at gmail.com
Thu Sep 5 06:07:41 UTC 2013
On 09/04/2013 11:36 PM, David M. Lloyd wrote:
> On 09/04/2013 02:56 PM, Daniel Fuchs wrote:
>> Hi,
>>
>> Please find below a changeset that will fix
>>
>> 8023168: Cleanup LogManager class initialization and
>> LogManager/LoggerContext relationship.
>>
>> <http://cr.openjdk.java.net/~dfuchs/webrev_8023168/webrev.00/>
>>
>> LogManager class initialization is fragile: because Logger
>> constructor calls LogManager.getLogManager, and because
>> LogManager calls new Logger during LogManager class initialization,
>> and because the global logger is instantiated during Logger class
>> initialization, loading Logger.class or LogManager.class can lead to
>> challenging hard to diagnose issues.
>
> As far as calling initialization ("ensureLogManagerInitialized()"),
> it's a shame that checking for a one-time action has to run through a
> synchronization block every time. Maybe a "lazy holder" class would
> be more appropriate here, especially given that the point seems to be
> to produce the RootLogger() instance which doubles as the indicator
> that initialization was done.
>
Or, without using yet another class, double-checked locking, like:
private volatile boolean initializedCalled;
final void ensureLogManagerInitialized() {
if (initializedCalled) {
return;
}
synchronized (this) {
final LogManager owner = this;
// re-check under lock
if (initializedCalled || owner != manager) {
// we don't want to do this twice, and we don't want to do
// this on private manager instances.
return;
}
try {
AccessController.doPrivileged(....);
} finally {
initializedCalled = true;
}
}
}
... the code in PrivilegedAction that does the initialization, that is,
the following statements:
owner.readPrimordialConfiguration();
* owner.rootLogger = owner.new RootLogger();*
owner.addLogger(owner.rootLogger);
final Logger global = Logger.global;
owner.addLogger(global);
...almost all of them (except assignment to rootLogger) by themselves
ensure that the state mutations they make are published to other
threads, so if also *rootLogger* field was made volatile, such
double-checked locking would presumably not be broken.
One observation on method readPrimordialConfiguration() - this method
performs similar double-checked locking initialization, but I think it
sets the *readPrimordialConfiguration* flag to soon. I think it should
do it in a final block of a try statement, like presented initialization
above.
Regards, Peter
More information about the core-libs-dev
mailing list