mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-28 15:24:43 +02:00
8307535: java.util.logging.Handlers should be more VirtualThread friendly
Reviewed-by: jpai
This commit is contained in:
parent
9fa8b9a4a6
commit
3c68c352fc
6 changed files with 307 additions and 33 deletions
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2001, 2023, 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
|
||||||
|
@ -85,13 +85,15 @@ public class ErrorManager {
|
||||||
* @param ex an exception (may be null)
|
* @param ex an exception (may be null)
|
||||||
* @param code an error code defined in ErrorManager
|
* @param code an error code defined in ErrorManager
|
||||||
*/
|
*/
|
||||||
public synchronized void error(String msg, Exception ex, int code) {
|
public void error(String msg, Exception ex, int code) {
|
||||||
|
synchronized (this) {
|
||||||
if (reported) {
|
if (reported) {
|
||||||
// We only report the first error, to avoid clogging
|
// We only report the first error, to avoid clogging
|
||||||
// the screen.
|
// the screen.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
reported = true;
|
reported = true;
|
||||||
|
}
|
||||||
String text = "java.util.logging.ErrorManager: " + code;
|
String text = "java.util.logging.ErrorManager: " + code;
|
||||||
if (msg != null) {
|
if (msg != null) {
|
||||||
text = text + ": " + msg;
|
text = text + ": " + msg;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2000, 2023, 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
|
||||||
|
@ -728,7 +728,21 @@ public class FileHandler extends StreamHandler {
|
||||||
/**
|
/**
|
||||||
* Rotate the set of output files
|
* Rotate the set of output files
|
||||||
*/
|
*/
|
||||||
private synchronized void rotate() {
|
private void rotate() {
|
||||||
|
if (tryUseLock()) {
|
||||||
|
try {
|
||||||
|
rotate0();
|
||||||
|
} finally {
|
||||||
|
unlock();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
synchronized (this) {
|
||||||
|
rotate0();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void rotate0() {
|
||||||
Level oldLevel = getLevel();
|
Level oldLevel = getLevel();
|
||||||
setLevel(Level.OFF);
|
setLevel(Level.OFF);
|
||||||
|
|
||||||
|
@ -760,9 +774,23 @@ public class FileHandler extends StreamHandler {
|
||||||
* @param record description of the log event. A null record is
|
* @param record description of the log event. A null record is
|
||||||
* silently ignored and is not published
|
* silently ignored and is not published
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("removal")
|
|
||||||
@Override
|
@Override
|
||||||
public synchronized void publish(LogRecord record) {
|
public void publish(LogRecord record) {
|
||||||
|
if (tryUseLock()) {
|
||||||
|
try {
|
||||||
|
publish0(record);
|
||||||
|
} finally {
|
||||||
|
unlock();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
synchronized (this) {
|
||||||
|
publish0(record);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
@SuppressWarnings("removal")
|
||||||
|
private void publish0(LogRecord record) {
|
||||||
if (!isLoggable(record)) {
|
if (!isLoggable(record)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -791,7 +819,21 @@ public class FileHandler extends StreamHandler {
|
||||||
* the caller does not have {@code LoggingPermission("control")}.
|
* the caller does not have {@code LoggingPermission("control")}.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public synchronized void close() throws SecurityException {
|
public void close() throws SecurityException {
|
||||||
|
if (tryUseLock()) {
|
||||||
|
try {
|
||||||
|
close0();
|
||||||
|
} finally {
|
||||||
|
unlock();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
synchronized (this) {
|
||||||
|
close0();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void close0() throws SecurityException {
|
||||||
super.close();
|
super.close();
|
||||||
// Unlock any lock file.
|
// Unlock any lock file.
|
||||||
if (lockFileName == null) {
|
if (lockFileName == null) {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2000, 2023, 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
|
||||||
|
@ -30,6 +30,7 @@ import java.util.Objects;
|
||||||
import java.io.UnsupportedEncodingException;
|
import java.io.UnsupportedEncodingException;
|
||||||
import java.security.AccessController;
|
import java.security.AccessController;
|
||||||
import java.security.PrivilegedAction;
|
import java.security.PrivilegedAction;
|
||||||
|
import java.util.concurrent.locks.ReentrantLock;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A {@code Handler} object takes log messages from a {@code Logger} and
|
* A {@code Handler} object takes log messages from a {@code Logger} and
|
||||||
|
@ -65,6 +66,7 @@ public abstract class Handler {
|
||||||
private volatile Level logLevel = Level.ALL;
|
private volatile Level logLevel = Level.ALL;
|
||||||
private volatile ErrorManager errorManager = new ErrorManager();
|
private volatile ErrorManager errorManager = new ErrorManager();
|
||||||
private volatile String encoding;
|
private volatile String encoding;
|
||||||
|
private final ReentrantLock lock;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default constructor. The resulting {@code Handler} has a log
|
* Default constructor. The resulting {@code Handler} has a log
|
||||||
|
@ -73,6 +75,17 @@ public abstract class Handler {
|
||||||
* as the {@code ErrorManager}.
|
* as the {@code ErrorManager}.
|
||||||
*/
|
*/
|
||||||
protected Handler() {
|
protected Handler() {
|
||||||
|
lock = initLocking();
|
||||||
|
}
|
||||||
|
|
||||||
|
private ReentrantLock initLocking() {
|
||||||
|
Class<?> clazz = this.getClass();
|
||||||
|
ClassLoader loader = clazz.getClassLoader();
|
||||||
|
if (loader != null && loader != ClassLoader.getPlatformClassLoader()) {
|
||||||
|
return null;
|
||||||
|
} else {
|
||||||
|
return new ReentrantLock();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -90,6 +103,7 @@ public abstract class Handler {
|
||||||
@SuppressWarnings("removal")
|
@SuppressWarnings("removal")
|
||||||
Handler(Level defaultLevel, Formatter defaultFormatter,
|
Handler(Level defaultLevel, Formatter defaultFormatter,
|
||||||
Formatter specifiedFormatter) {
|
Formatter specifiedFormatter) {
|
||||||
|
this();
|
||||||
|
|
||||||
LogManager manager = LogManager.getLogManager();
|
LogManager manager = LogManager.getLogManager();
|
||||||
String cname = getClass().getName();
|
String cname = getClass().getName();
|
||||||
|
@ -122,6 +136,15 @@ public abstract class Handler {
|
||||||
}, null, LogManager.controlPermission);
|
}, null, LogManager.controlPermission);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boolean tryUseLock() {
|
||||||
|
if (lock == null) return false;
|
||||||
|
lock.lock();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
void unlock() {
|
||||||
|
lock.unlock();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Publish a {@code LogRecord}.
|
* Publish a {@code LogRecord}.
|
||||||
* <p>
|
* <p>
|
||||||
|
@ -165,7 +188,21 @@ public abstract class Handler {
|
||||||
* @throws SecurityException if a security manager exists and if
|
* @throws SecurityException if a security manager exists and if
|
||||||
* the caller does not have {@code LoggingPermission("control")}.
|
* the caller does not have {@code LoggingPermission("control")}.
|
||||||
*/
|
*/
|
||||||
public synchronized void setFormatter(Formatter newFormatter) throws SecurityException {
|
public void setFormatter(Formatter newFormatter) throws SecurityException {
|
||||||
|
if (tryUseLock()) {
|
||||||
|
try {
|
||||||
|
setFormatter0(newFormatter);
|
||||||
|
} finally {
|
||||||
|
unlock();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
synchronized (this) {
|
||||||
|
setFormatter0(newFormatter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setFormatter0(Formatter newFormatter) throws SecurityException {
|
||||||
checkPermission();
|
checkPermission();
|
||||||
formatter = Objects.requireNonNull(newFormatter);
|
formatter = Objects.requireNonNull(newFormatter);
|
||||||
}
|
}
|
||||||
|
@ -191,7 +228,22 @@ public abstract class Handler {
|
||||||
* @throws UnsupportedEncodingException if the named encoding is
|
* @throws UnsupportedEncodingException if the named encoding is
|
||||||
* not supported.
|
* not supported.
|
||||||
*/
|
*/
|
||||||
public synchronized void setEncoding(String encoding)
|
public void setEncoding(String encoding)
|
||||||
|
throws SecurityException, java.io.UnsupportedEncodingException {
|
||||||
|
if (tryUseLock()) {
|
||||||
|
try {
|
||||||
|
setEncoding0(encoding);
|
||||||
|
} finally {
|
||||||
|
unlock();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
synchronized (this) {
|
||||||
|
setEncoding0(encoding);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setEncoding0(String encoding)
|
||||||
throws SecurityException, java.io.UnsupportedEncodingException {
|
throws SecurityException, java.io.UnsupportedEncodingException {
|
||||||
checkPermission();
|
checkPermission();
|
||||||
if (encoding != null) {
|
if (encoding != null) {
|
||||||
|
@ -227,7 +279,21 @@ public abstract class Handler {
|
||||||
* @throws SecurityException if a security manager exists and if
|
* @throws SecurityException if a security manager exists and if
|
||||||
* the caller does not have {@code LoggingPermission("control")}.
|
* the caller does not have {@code LoggingPermission("control")}.
|
||||||
*/
|
*/
|
||||||
public synchronized void setFilter(Filter newFilter) throws SecurityException {
|
public void setFilter(Filter newFilter) throws SecurityException {
|
||||||
|
if (tryUseLock()) {
|
||||||
|
try {
|
||||||
|
setFilter0(newFilter);
|
||||||
|
} finally {
|
||||||
|
unlock();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
synchronized (this) {
|
||||||
|
setFilter0(newFilter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setFilter0(Filter newFilter) throws SecurityException {
|
||||||
checkPermission();
|
checkPermission();
|
||||||
filter = newFilter;
|
filter = newFilter;
|
||||||
}
|
}
|
||||||
|
@ -251,7 +317,21 @@ public abstract class Handler {
|
||||||
* @throws SecurityException if a security manager exists and if
|
* @throws SecurityException if a security manager exists and if
|
||||||
* the caller does not have {@code LoggingPermission("control")}.
|
* the caller does not have {@code LoggingPermission("control")}.
|
||||||
*/
|
*/
|
||||||
public synchronized void setErrorManager(ErrorManager em) {
|
public void setErrorManager(ErrorManager em) {
|
||||||
|
if (tryUseLock()) {
|
||||||
|
try {
|
||||||
|
setErrorManager0(em);
|
||||||
|
} finally {
|
||||||
|
unlock();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
synchronized (this) {
|
||||||
|
setErrorManager0(em);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setErrorManager0(ErrorManager em) {
|
||||||
checkPermission();
|
checkPermission();
|
||||||
if (em == null) {
|
if (em == null) {
|
||||||
throw new NullPointerException();
|
throw new NullPointerException();
|
||||||
|
@ -303,7 +383,21 @@ public abstract class Handler {
|
||||||
* @throws SecurityException if a security manager exists and if
|
* @throws SecurityException if a security manager exists and if
|
||||||
* the caller does not have {@code LoggingPermission("control")}.
|
* the caller does not have {@code LoggingPermission("control")}.
|
||||||
*/
|
*/
|
||||||
public synchronized void setLevel(Level newLevel) throws SecurityException {
|
public void setLevel(Level newLevel) throws SecurityException {
|
||||||
|
if (tryUseLock()) {
|
||||||
|
try {
|
||||||
|
setLevel0(newLevel);
|
||||||
|
} finally {
|
||||||
|
unlock();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
synchronized (this) {
|
||||||
|
setLevel0(newLevel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setLevel0(Level newLevel) throws SecurityException {
|
||||||
if (newLevel == null) {
|
if (newLevel == null) {
|
||||||
throw new NullPointerException();
|
throw new NullPointerException();
|
||||||
}
|
}
|
||||||
|
@ -311,6 +405,8 @@ public abstract class Handler {
|
||||||
logLevel = newLevel;
|
logLevel = newLevel;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the log level specifying which messages will be
|
* Get the log level specifying which messages will be
|
||||||
* logged by this {@code Handler}. Message levels lower
|
* logged by this {@code Handler}. Message levels lower
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2000, 2023, 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
|
||||||
|
@ -178,7 +178,21 @@ public class MemoryHandler extends Handler {
|
||||||
* silently ignored and is not published
|
* silently ignored and is not published
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public synchronized void publish(LogRecord record) {
|
public void publish(LogRecord record) {
|
||||||
|
if (tryUseLock()) {
|
||||||
|
try {
|
||||||
|
publish0(record);
|
||||||
|
} finally {
|
||||||
|
unlock();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
synchronized (this) {
|
||||||
|
publish0(record);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void publish0(LogRecord record) {
|
||||||
if (!isLoggable(record)) {
|
if (!isLoggable(record)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -200,7 +214,21 @@ public class MemoryHandler extends Handler {
|
||||||
* <p>
|
* <p>
|
||||||
* The buffer is then cleared.
|
* The buffer is then cleared.
|
||||||
*/
|
*/
|
||||||
public synchronized void push() {
|
public void push() {
|
||||||
|
if (tryUseLock()) {
|
||||||
|
try {
|
||||||
|
push0();
|
||||||
|
} finally {
|
||||||
|
unlock();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
synchronized (this) {
|
||||||
|
push0();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void push0() {
|
||||||
for (int i = 0; i < count; i++) {
|
for (int i = 0; i < count; i++) {
|
||||||
int ix = (start+i)%buffer.length;
|
int ix = (start+i)%buffer.length;
|
||||||
LogRecord record = buffer[ix];
|
LogRecord record = buffer[ix];
|
||||||
|
@ -244,7 +272,21 @@ public class MemoryHandler extends Handler {
|
||||||
* @throws SecurityException if a security manager exists and if
|
* @throws SecurityException if a security manager exists and if
|
||||||
* the caller does not have {@code LoggingPermission("control")}.
|
* the caller does not have {@code LoggingPermission("control")}.
|
||||||
*/
|
*/
|
||||||
public synchronized void setPushLevel(Level newLevel) throws SecurityException {
|
public void setPushLevel(Level newLevel) throws SecurityException {
|
||||||
|
if (tryUseLock()) {
|
||||||
|
try {
|
||||||
|
setPushLevel0(newLevel);
|
||||||
|
} finally {
|
||||||
|
unlock();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
synchronized (this) {
|
||||||
|
setPushLevel0(newLevel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setPushLevel0(Level newLevel) throws SecurityException {
|
||||||
if (newLevel == null) {
|
if (newLevel == null) {
|
||||||
throw new NullPointerException();
|
throw new NullPointerException();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2000, 2023, 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
|
||||||
|
@ -156,7 +156,21 @@ public class SocketHandler extends StreamHandler {
|
||||||
* the caller does not have {@code LoggingPermission("control")}.
|
* the caller does not have {@code LoggingPermission("control")}.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public synchronized void close() throws SecurityException {
|
public void close() throws SecurityException {
|
||||||
|
if (tryUseLock()) {
|
||||||
|
try {
|
||||||
|
close0();
|
||||||
|
} finally {
|
||||||
|
unlock();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
synchronized (this) {
|
||||||
|
close0();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void close0() throws SecurityException {
|
||||||
super.close();
|
super.close();
|
||||||
if (sock != null) {
|
if (sock != null) {
|
||||||
try {
|
try {
|
||||||
|
@ -175,7 +189,21 @@ public class SocketHandler extends StreamHandler {
|
||||||
* silently ignored and is not published
|
* silently ignored and is not published
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public synchronized void publish(LogRecord record) {
|
public void publish(LogRecord record) {
|
||||||
|
if (tryUseLock()) {
|
||||||
|
try {
|
||||||
|
publish0(record);
|
||||||
|
} finally {
|
||||||
|
unlock();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
synchronized (this) {
|
||||||
|
publish0(record);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void publish0(LogRecord record) {
|
||||||
if (!isLoggable(record)) {
|
if (!isLoggable(record)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2000, 2023, 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
|
||||||
|
@ -122,7 +122,21 @@ public class StreamHandler extends Handler {
|
||||||
* @throws SecurityException if a security manager exists and if
|
* @throws SecurityException if a security manager exists and if
|
||||||
* the caller does not have {@code LoggingPermission("control")}.
|
* the caller does not have {@code LoggingPermission("control")}.
|
||||||
*/
|
*/
|
||||||
protected synchronized void setOutputStream(OutputStream out) throws SecurityException {
|
protected void setOutputStream(OutputStream out) throws SecurityException {
|
||||||
|
if (tryUseLock()) {
|
||||||
|
try {
|
||||||
|
setOutputStream0(out);
|
||||||
|
} finally {
|
||||||
|
unlock();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
synchronized (this) {
|
||||||
|
setOutputStream0(out);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setOutputStream0(OutputStream out) throws SecurityException {
|
||||||
if (out == null) {
|
if (out == null) {
|
||||||
throw new NullPointerException();
|
throw new NullPointerException();
|
||||||
}
|
}
|
||||||
|
@ -157,7 +171,21 @@ public class StreamHandler extends Handler {
|
||||||
* not supported.
|
* not supported.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public synchronized void setEncoding(String encoding)
|
public void setEncoding(String encoding)
|
||||||
|
throws SecurityException, java.io.UnsupportedEncodingException {
|
||||||
|
if (tryUseLock()) {
|
||||||
|
try {
|
||||||
|
setEncoding0(encoding);
|
||||||
|
} finally {
|
||||||
|
unlock();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
synchronized (this) {
|
||||||
|
setEncoding0(encoding);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private void setEncoding0(String encoding)
|
||||||
throws SecurityException, java.io.UnsupportedEncodingException {
|
throws SecurityException, java.io.UnsupportedEncodingException {
|
||||||
super.setEncoding(encoding);
|
super.setEncoding(encoding);
|
||||||
if (output == null) {
|
if (output == null) {
|
||||||
|
@ -190,7 +218,20 @@ public class StreamHandler extends Handler {
|
||||||
* silently ignored and is not published
|
* silently ignored and is not published
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public synchronized void publish(LogRecord record) {
|
public void publish(LogRecord record) {
|
||||||
|
if (tryUseLock()) {
|
||||||
|
try {
|
||||||
|
publish0(record);
|
||||||
|
} finally {
|
||||||
|
unlock();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
synchronized (this) {
|
||||||
|
publish0(record);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private void publish0(LogRecord record) {
|
||||||
if (!isLoggable(record)) {
|
if (!isLoggable(record)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -241,7 +282,20 @@ public class StreamHandler extends Handler {
|
||||||
* Flush any buffered messages.
|
* Flush any buffered messages.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public synchronized void flush() {
|
public void flush() {
|
||||||
|
if (tryUseLock()) {
|
||||||
|
try {
|
||||||
|
flush0();
|
||||||
|
} finally {
|
||||||
|
unlock();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
synchronized (this) {
|
||||||
|
flush0();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private void flush0() {
|
||||||
if (writer != null) {
|
if (writer != null) {
|
||||||
try {
|
try {
|
||||||
writer.flush();
|
writer.flush();
|
||||||
|
@ -253,7 +307,7 @@ public class StreamHandler extends Handler {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private synchronized void flushAndClose() throws SecurityException {
|
private void flushAndClose() throws SecurityException {
|
||||||
checkPermission();
|
checkPermission();
|
||||||
if (writer != null) {
|
if (writer != null) {
|
||||||
try {
|
try {
|
||||||
|
@ -286,8 +340,18 @@ public class StreamHandler extends Handler {
|
||||||
* the caller does not have LoggingPermission("control").
|
* the caller does not have LoggingPermission("control").
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public synchronized void close() throws SecurityException {
|
public void close() throws SecurityException {
|
||||||
|
if (tryUseLock()) {
|
||||||
|
try {
|
||||||
flushAndClose();
|
flushAndClose();
|
||||||
|
} finally {
|
||||||
|
unlock();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
synchronized (this) {
|
||||||
|
flushAndClose();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Package-private support for setting OutputStream
|
// Package-private support for setting OutputStream
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue