< prev index next >
src/java.base/share/classes/java/io/FileOutputStream.java
Print this page
rev 15897 : 8168640: (fc) Avoiding AtomicBoolean in FileInput/-OutputStream improves startup
Reviewed-by: alanb, shade, plevart
*** 1,7 ****
/*
! * Copyright (c) 1994, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
--- 1,7 ----
/*
! * Copyright (c) 1994, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
*** 24,34 ****
*/
package java.io;
import java.nio.channels.FileChannel;
- import java.util.concurrent.atomic.AtomicBoolean;
import jdk.internal.misc.SharedSecrets;
import jdk.internal.misc.JavaIOFileDescriptorAccess;
import sun.nio.ch.FileChannelImpl;
--- 24,33 ----
*** 75,85 ****
* The path of the referenced file
* (null if the stream is created with a file descriptor)
*/
private final String path;
! private final AtomicBoolean closed = new AtomicBoolean(false);
/**
* Creates a file output stream to write to the file with the
* specified name. A new <code>FileDescriptor</code> object is
* created to represent this file connection.
--- 74,86 ----
* The path of the referenced file
* (null if the stream is created with a file descriptor)
*/
private final String path;
! private final Object closeLock = new Object();
!
! private volatile boolean closed;
/**
* Creates a file output stream to write to the file with the
* specified name. A new <code>FileDescriptor</code> object is
* created to represent this file connection.
*** 339,355 ****
*
* @revised 1.4
* @spec JSR-51
*/
public void close() throws IOException {
! if (!closed.compareAndSet(false, true)) {
! // if compareAndSet() returns false closed was already true
return;
}
FileChannel fc = channel;
if (fc != null) {
fc.close();
}
fd.closeAll(new Closeable() {
public void close() throws IOException {
--- 340,363 ----
*
* @revised 1.4
* @spec JSR-51
*/
public void close() throws IOException {
! if (closed) {
! return;
! }
! synchronized (closeLock) {
! if (closed) {
return;
}
+ closed = true;
+ }
FileChannel fc = channel;
if (fc != null) {
+ // possible race with getChannel(), benign since
+ // FileChannel.close is final and idempotent
fc.close();
}
fd.closeAll(new Closeable() {
public void close() throws IOException {
*** 397,408 ****
if (fc == null) {
synchronized (this) {
fc = this.channel;
if (fc == null) {
this.channel = fc = FileChannelImpl.open(fd, path, false, true, this);
! if (closed.get()) {
try {
fc.close();
} catch (IOException ioe) {
throw new InternalError(ioe); // should not happen
}
}
--- 405,418 ----
if (fc == null) {
synchronized (this) {
fc = this.channel;
if (fc == null) {
this.channel = fc = FileChannelImpl.open(fd, path, false, true, this);
! if (closed) {
try {
+ // possible race with close(), benign since
+ // FileChannel.close is final and idempotent
fc.close();
} catch (IOException ioe) {
throw new InternalError(ioe); // should not happen
}
}
< prev index next >