Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/solaris/classes/sun/nio/ch/SinkChannelImpl.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 SinkChannelImpl34extends Pipe.SinkChannel35implements 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 write, 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}7677SinkChannelImpl(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.POLLOUT) != 0) &&130((intOps & SelectionKey.OP_WRITE) != 0))131newOps |= SelectionKey.OP_WRITE;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_WRITE)147ops = Net.POLLOUT;148sk.selector.putEventOps(sk, ops);149}150151private void ensureOpen() throws IOException {152if (!isOpen())153throw new ClosedChannelException();154}155156public int write(ByteBuffer src) throws IOException {157ensureOpen();158synchronized (lock) {159int n = 0;160try {161begin();162if (!isOpen())163return 0;164thread = NativeThread.current();165do {166n = IOUtil.write(fd, src, -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 write(ByteBuffer[] srcs) throws IOException {178if (srcs == null)179throw new NullPointerException();180ensureOpen();181synchronized (lock) {182long n = 0;183try {184begin();185if (!isOpen())186return 0;187thread = NativeThread.current();188do {189n = IOUtil.write(fd, srcs, nd);190} while ((n == IOStatus.INTERRUPTED) && isOpen());191return IOStatus.normalize(n);192} finally {193thread = 0;194end((n > 0) || (n == IOStatus.UNAVAILABLE));195assert IOStatus.check(n);196}197}198}199200public long write(ByteBuffer[] srcs, int offset, int length)201throws IOException202{203if ((offset < 0) || (length < 0) || (offset > srcs.length - length))204throw new IndexOutOfBoundsException();205return write(Util.subsequence(srcs, offset, length));206}207}208209210