Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/solaris/classes/sun/nio/ch/SourceChannelImpl.java
32288 views
/*1* Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package sun.nio.ch;2627import java.io.*;28import java.nio.ByteBuffer;29import java.nio.channels.*;30import java.nio.channels.spi.*;313233class SourceChannelImpl34extends Pipe.SourceChannel35implements SelChImpl36{3738// Used to make native read and write calls39private static final NativeDispatcher nd = new FileDispatcherImpl();4041// The file descriptor associated with this channel42FileDescriptor fd;4344// fd value needed for dev/poll. This value will remain valid45// even after the value in the file descriptor object has been set to -146int fdVal;4748// ID of native thread doing read, for signalling49private volatile long thread = 0;5051// Lock held by current reading thread52private final Object lock = new Object();5354// Lock held by any thread that modifies the state fields declared below55// DO NOT invoke a blocking I/O operation while holding this lock!56private final Object stateLock = new Object();5758// -- The following fields are protected by stateLock5960// Channel state61private static final int ST_UNINITIALIZED = -1;62private static final int ST_INUSE = 0;63private static final int ST_KILLED = 1;64private volatile int state = ST_UNINITIALIZED;6566// -- End of fields protected by stateLock676869public FileDescriptor getFD() {70return fd;71}7273public int getFDVal() {74return fdVal;75}7677SourceChannelImpl(SelectorProvider sp, FileDescriptor fd) {78super(sp);79this.fd = fd;80this.fdVal = IOUtil.fdVal(fd);81this.state = ST_INUSE;82}8384protected void implCloseSelectableChannel() throws IOException {85synchronized (stateLock) {86if (state != ST_KILLED)87nd.preClose(fd);88long th = thread;89if (th != 0)90NativeThread.signal(th);91if (!isRegistered())92kill();93}94}9596public void kill() throws IOException {97synchronized (stateLock) {98if (state == ST_KILLED)99return;100if (state == ST_UNINITIALIZED) {101state = ST_KILLED;102return;103}104assert !isOpen() && !isRegistered();105nd.close(fd);106state = ST_KILLED;107}108}109110protected void implConfigureBlocking(boolean block) throws IOException {111IOUtil.configureBlocking(fd, block);112}113114public boolean translateReadyOps(int ops, int initialOps,115SelectionKeyImpl sk) {116int intOps = sk.nioInterestOps(); // Do this just once, it synchronizes117int oldOps = sk.nioReadyOps();118int newOps = initialOps;119120if ((ops & Net.POLLNVAL) != 0)121throw new Error("POLLNVAL detected");122123if ((ops & (Net.POLLERR | Net.POLLHUP)) != 0) {124newOps = intOps;125sk.nioReadyOps(newOps);126return (newOps & ~oldOps) != 0;127}128129if (((ops & Net.POLLIN) != 0) &&130((intOps & SelectionKey.OP_READ) != 0))131newOps |= SelectionKey.OP_READ;132133sk.nioReadyOps(newOps);134return (newOps & ~oldOps) != 0;135}136137public boolean translateAndUpdateReadyOps(int ops, SelectionKeyImpl sk) {138return translateReadyOps(ops, sk.nioReadyOps(), sk);139}140141public boolean translateAndSetReadyOps(int ops, SelectionKeyImpl sk) {142return translateReadyOps(ops, 0, sk);143}144145public void translateAndSetInterestOps(int ops, SelectionKeyImpl sk) {146if (ops == SelectionKey.OP_READ)147ops = Net.POLLIN;148sk.selector.putEventOps(sk, ops);149}150151private void ensureOpen() throws IOException {152if (!isOpen())153throw new ClosedChannelException();154}155156public int read(ByteBuffer dst) throws IOException {157ensureOpen();158synchronized (lock) {159int n = 0;160try {161begin();162if (!isOpen())163return 0;164thread = NativeThread.current();165do {166n = IOUtil.read(fd, dst, -1, nd);167} while ((n == IOStatus.INTERRUPTED) && isOpen());168return IOStatus.normalize(n);169} finally {170thread = 0;171end((n > 0) || (n == IOStatus.UNAVAILABLE));172assert IOStatus.check(n);173}174}175}176177public long read(ByteBuffer[] dsts, int offset, int length)178throws IOException179{180if ((offset < 0) || (length < 0) || (offset > dsts.length - length))181throw new IndexOutOfBoundsException();182return read(Util.subsequence(dsts, offset, length));183}184185public long read(ByteBuffer[] dsts) throws IOException {186if (dsts == null)187throw new NullPointerException();188ensureOpen();189synchronized (lock) {190long n = 0;191try {192begin();193if (!isOpen())194return 0;195thread = NativeThread.current();196do {197n = IOUtil.read(fd, dsts, nd);198} while ((n == IOStatus.INTERRUPTED) && isOpen());199return IOStatus.normalize(n);200} finally {201thread = 0;202end((n > 0) || (n == IOStatus.UNAVAILABLE));203assert IOStatus.check(n);204}205}206}207}208209210