< 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 >