src/solaris/classes/java/io/FileDescriptor.java

Print this page

        

*** 1,7 **** /* ! * Copyright (c) 1995, 2008, 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) 1995, 2011, 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
*** 23,33 **** * questions. */ package java.io; ! import java.util.concurrent.atomic.AtomicInteger; /** * Instances of the file descriptor class serve as an opaque handle * to the underlying machine-specific structure representing an open * file, an open socket, or another source or sink of bytes. The --- 23,34 ---- * questions. */ package java.io; ! import java.util.ArrayList; ! import java.util.List; /** * Instances of the file descriptor class serve as an opaque handle * to the underlying machine-specific structure representing an open * file, an open socket, or another source or sink of bytes. The
*** 44,72 **** */ public final class FileDescriptor { private int fd; ! /** ! * A counter for tracking the FIS/FOS/RAF instances that ! * use this FileDescriptor. The FIS/FOS.finalize() will not release ! * the FileDescriptor if it is still under user by a stream. ! */ ! private AtomicInteger useCount; /** * Constructs an (invalid) FileDescriptor * object. */ public /**/ FileDescriptor() { fd = -1; - useCount = new AtomicInteger(); } private /* */ FileDescriptor(int fd) { this.fd = fd; - useCount = new AtomicInteger(); } /** * A handle to the standard input stream. Usually, this file * descriptor is not used directly, but rather via the input stream --- 45,68 ---- */ public final class FileDescriptor { private int fd; ! private Closeable parent; ! private List<Closeable> otherParents; ! private boolean closed; /** * Constructs an (invalid) FileDescriptor * object. */ public /**/ FileDescriptor() { fd = -1; } private /* */ FileDescriptor(int fd) { this.fd = fd; } /** * A handle to the standard input stream. Usually, this file * descriptor is not used directly, but rather via the input stream
*** 162,176 **** } } ); } ! // package private methods used by FIS, FOS and RAF ! int incrementAndGetUseCount() { ! return useCount.incrementAndGet(); } ! int decrementAndGetUseCount() { ! return useCount.decrementAndGet(); } } --- 158,226 ---- } } ); } ! /* ! * Package private methods to track referents. ! * If multiple streams point to the same FileDescriptor, we cycle ! * through the list of all referents and call close() ! */ ! /** ! * Attach a Closeable to this FD for tracking. ! * parent reference is added to otherParents when ! * needed to make closeAll simpler. ! */ ! synchronized void attach(Closeable c) { ! if (parent == null) { ! // first caller gets to do this ! parent = c; ! } else if (otherParents == null) { ! otherParents = new ArrayList<>(); ! otherParents.add(parent); ! otherParents.add(c); ! } else { ! otherParents.add(c); } + } ! /** ! * Cycle through all Closeables sharing this FD and call ! * close() on each one. ! * ! * The caller closeable gets to call close0(). ! */ ! @SuppressWarnings("try") ! synchronized void closeAll(Closeable releaser) throws IOException { ! if (!closed) { ! closed = true; ! IOException ioe = null; ! try (Closeable c = releaser) { ! if (otherParents != null) { ! for (Closeable referent : otherParents) { ! try { ! referent.close(); ! } catch(IOException x) { ! if (ioe == null) { ! ioe = x; ! } else { ! ioe.addSuppressed(x); } + } + } + } + } catch(IOException ex) { + /* + * If releaser close() throws IOException + * add other exceptions as suppressed. + */ + if (ioe != null) + ex.addSuppressed(ioe); + ioe = ex; + } finally { + if (ioe != null) + throw ioe; + } + } + } }