mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-27 06:45:07 +02:00
8196956: (ch) More channels cleanup
Reviewed-by: rriggs, prappo, bpb
This commit is contained in:
parent
48aad3bd2f
commit
e3b7698786
8 changed files with 107 additions and 62 deletions
|
@ -121,7 +121,7 @@ public abstract class SelectableChannel
|
|||
// keySet, may be empty but is never null, typ. a tiny array
|
||||
// boolean isRegistered, protected by key set
|
||||
// regLock, lock object to prevent duplicate registrations
|
||||
// boolean isBlocking, protected by regLock
|
||||
// blocking mode, protected by regLock
|
||||
|
||||
/**
|
||||
* Tells whether or not this channel is currently registered with any
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2000, 2018, 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
|
||||
|
@ -26,7 +26,14 @@
|
|||
package java.nio.channels.spi;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.channels.*;
|
||||
import java.nio.channels.CancelledKeyException;
|
||||
import java.nio.channels.ClosedChannelException;
|
||||
import java.nio.channels.ClosedSelectorException;
|
||||
import java.nio.channels.IllegalBlockingModeException;
|
||||
import java.nio.channels.IllegalSelectorException;
|
||||
import java.nio.channels.SelectableChannel;
|
||||
import java.nio.channels.SelectionKey;
|
||||
import java.nio.channels.Selector;
|
||||
|
||||
|
||||
/**
|
||||
|
@ -67,8 +74,8 @@ public abstract class AbstractSelectableChannel
|
|||
// Lock for registration and configureBlocking operations
|
||||
private final Object regLock = new Object();
|
||||
|
||||
// Blocking mode, protected by regLock
|
||||
boolean blocking = true;
|
||||
// True when non-blocking, need regLock to change;
|
||||
private volatile boolean nonBlocking;
|
||||
|
||||
/**
|
||||
* Initializes a new instance of this class.
|
||||
|
@ -197,7 +204,7 @@ public abstract class AbstractSelectableChannel
|
|||
throw new ClosedChannelException();
|
||||
if ((ops & ~validOps()) != 0)
|
||||
throw new IllegalArgumentException();
|
||||
if (blocking)
|
||||
if (isBlocking())
|
||||
throw new IllegalBlockingModeException();
|
||||
SelectionKey k = findKey(sel);
|
||||
if (k != null) {
|
||||
|
@ -264,9 +271,7 @@ public abstract class AbstractSelectableChannel
|
|||
// -- Blocking --
|
||||
|
||||
public final boolean isBlocking() {
|
||||
synchronized (regLock) {
|
||||
return blocking;
|
||||
}
|
||||
return !nonBlocking;
|
||||
}
|
||||
|
||||
public final Object blockingLock() {
|
||||
|
@ -287,12 +292,13 @@ public abstract class AbstractSelectableChannel
|
|||
synchronized (regLock) {
|
||||
if (!isOpen())
|
||||
throw new ClosedChannelException();
|
||||
if (blocking == block)
|
||||
return this;
|
||||
if (block && haveValidKeys())
|
||||
throw new IllegalBlockingModeException();
|
||||
implConfigureBlocking(block);
|
||||
blocking = block;
|
||||
boolean blocking = !nonBlocking;
|
||||
if (block != blocking) {
|
||||
if (block && haveValidKeys())
|
||||
throw new IllegalBlockingModeException();
|
||||
implConfigureBlocking(block);
|
||||
nonBlocking = !block;
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
|
|
@ -70,9 +70,6 @@ class DatagramChannelImpl
|
|||
|
||||
// Our file descriptor
|
||||
private final FileDescriptor fd;
|
||||
|
||||
// fd value needed for dev/poll. This value will remain valid
|
||||
// even after the value in the file descriptor object has been set to -1
|
||||
private final int fdVal;
|
||||
|
||||
// The protocol family of the socket
|
||||
|
@ -124,7 +121,6 @@ class DatagramChannelImpl
|
|||
|
||||
// -- End of fields protected by stateLock
|
||||
|
||||
|
||||
public DatagramChannelImpl(SelectorProvider sp)
|
||||
throws IOException
|
||||
{
|
||||
|
@ -159,16 +155,27 @@ class DatagramChannelImpl
|
|||
throw new UnsupportedOperationException("IPv6 not available");
|
||||
}
|
||||
}
|
||||
this.family = family;
|
||||
this.fd = Net.socket(family, false);
|
||||
this.fdVal = IOUtil.fdVal(fd);
|
||||
this.state = ST_UNCONNECTED;
|
||||
|
||||
ResourceManager.beforeUdpCreate();
|
||||
try {
|
||||
this.family = family;
|
||||
this.fd = Net.socket(family, false);
|
||||
this.fdVal = IOUtil.fdVal(fd);
|
||||
this.state = ST_UNCONNECTED;
|
||||
} catch (IOException ioe) {
|
||||
ResourceManager.afterUdpClose();
|
||||
throw ioe;
|
||||
}
|
||||
}
|
||||
|
||||
public DatagramChannelImpl(SelectorProvider sp, FileDescriptor fd)
|
||||
throws IOException
|
||||
{
|
||||
super(sp);
|
||||
|
||||
// increment UDP count to match decrement when closing
|
||||
ResourceManager.beforeUdpCreate();
|
||||
|
||||
this.family = Net.isIPv6Available() ?
|
||||
StandardProtocolFamily.INET6 : StandardProtocolFamily.INET;
|
||||
this.fd = fd;
|
||||
|
@ -790,10 +797,9 @@ class DatagramChannelImpl
|
|||
localAddress = Net.localAddress(fd);
|
||||
|
||||
// flush any packets already received.
|
||||
boolean blocking = false;
|
||||
synchronized (blockingLock()) {
|
||||
boolean blocking = isBlocking();
|
||||
try {
|
||||
blocking = isBlocking();
|
||||
ByteBuffer tmpBuf = ByteBuffer.allocate(100);
|
||||
if (blocking) {
|
||||
configureBlocking(false);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2001, 2018, 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
|
||||
|
@ -25,10 +25,22 @@
|
|||
|
||||
package sun.nio.ch;
|
||||
|
||||
import java.io.*;
|
||||
import java.net.*;
|
||||
import java.nio.*;
|
||||
import java.nio.channels.*;
|
||||
import java.io.IOException;
|
||||
import java.net.DatagramPacket;
|
||||
import java.net.DatagramSocket;
|
||||
import java.net.DatagramSocketImpl;
|
||||
import java.net.InetAddress;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.NetworkInterface;
|
||||
import java.net.SocketAddress;
|
||||
import java.net.SocketException;
|
||||
import java.net.SocketOption;
|
||||
import java.net.SocketTimeoutException;
|
||||
import java.net.StandardSocketOptions;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.channels.ClosedChannelException;
|
||||
import java.nio.channels.DatagramChannel;
|
||||
import java.nio.channels.IllegalBlockingModeException;
|
||||
|
||||
|
||||
// Make a datagram-socket channel look like a datagram socket.
|
||||
|
@ -178,7 +190,6 @@ public class DatagramSocketAdaptor
|
|||
|
||||
dc.configureBlocking(false);
|
||||
try {
|
||||
int n;
|
||||
SocketAddress sender;
|
||||
if ((sender = dc.receive(bb)) != null)
|
||||
return sender;
|
||||
|
@ -188,19 +199,18 @@ public class DatagramSocketAdaptor
|
|||
throw new ClosedChannelException();
|
||||
long st = System.currentTimeMillis();
|
||||
int result = dc.poll(Net.POLLIN, to);
|
||||
if (result > 0 &&
|
||||
((result & Net.POLLIN) != 0)) {
|
||||
if (result > 0 && ((result & Net.POLLIN) != 0)) {
|
||||
if ((sender = dc.receive(bb)) != null)
|
||||
return sender;
|
||||
}
|
||||
to -= System.currentTimeMillis() - st;
|
||||
if (to <= 0)
|
||||
throw new SocketTimeoutException();
|
||||
|
||||
}
|
||||
} finally {
|
||||
if (dc.isOpen())
|
||||
try {
|
||||
dc.configureBlocking(true);
|
||||
} catch (ClosedChannelException e) { }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2000, 2018, 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
|
||||
|
@ -25,9 +25,20 @@
|
|||
|
||||
package sun.nio.ch;
|
||||
|
||||
import java.io.*;
|
||||
import java.net.*;
|
||||
import java.nio.channels.*;
|
||||
import java.io.IOException;
|
||||
import java.net.InetAddress;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.ServerSocket;
|
||||
import java.net.Socket;
|
||||
import java.net.SocketAddress;
|
||||
import java.net.SocketException;
|
||||
import java.net.SocketTimeoutException;
|
||||
import java.net.StandardSocketOptions;
|
||||
import java.nio.channels.ClosedChannelException;
|
||||
import java.nio.channels.IllegalBlockingModeException;
|
||||
import java.nio.channels.NotYetBoundException;
|
||||
import java.nio.channels.ServerSocketChannel;
|
||||
import java.nio.channels.SocketChannel;
|
||||
|
||||
|
||||
// Make a server-socket channel look like a server socket.
|
||||
|
@ -37,7 +48,7 @@ import java.nio.channels.*;
|
|||
// class.
|
||||
//
|
||||
|
||||
public class ServerSocketAdaptor // package-private
|
||||
class ServerSocketAdaptor // package-private
|
||||
extends ServerSocket
|
||||
{
|
||||
|
||||
|
@ -96,13 +107,18 @@ public class ServerSocketAdaptor // package-private
|
|||
try {
|
||||
if (!ssc.isBound())
|
||||
throw new NotYetBoundException();
|
||||
|
||||
if (timeout == 0) {
|
||||
// for compatibility reasons: accept connection if available
|
||||
// when configured non-blocking
|
||||
SocketChannel sc = ssc.accept();
|
||||
if (sc == null && !ssc.isBlocking())
|
||||
throw new IllegalBlockingModeException();
|
||||
return sc.socket();
|
||||
}
|
||||
|
||||
if (!ssc.isBlocking())
|
||||
throw new IllegalBlockingModeException();
|
||||
ssc.configureBlocking(false);
|
||||
try {
|
||||
SocketChannel sc;
|
||||
|
@ -121,10 +137,10 @@ public class ServerSocketAdaptor // package-private
|
|||
throw new SocketTimeoutException();
|
||||
}
|
||||
} finally {
|
||||
if (ssc.isOpen())
|
||||
try {
|
||||
ssc.configureBlocking(true);
|
||||
} catch (ClosedChannelException e) { }
|
||||
}
|
||||
|
||||
} catch (Exception x) {
|
||||
Net.translateException(x);
|
||||
assert false;
|
||||
|
@ -178,8 +194,7 @@ public class ServerSocketAdaptor // package-private
|
|||
if (!isBound())
|
||||
return "ServerSocket[unbound]";
|
||||
return "ServerSocket[addr=" + getInetAddress() +
|
||||
// ",port=" + getPort() +
|
||||
",localport=" + getLocalPort() + "]";
|
||||
",localport=" + getLocalPort() + "]";
|
||||
}
|
||||
|
||||
public void setReceiveBufferSize(int size) throws SocketException {
|
||||
|
|
|
@ -62,10 +62,7 @@ class ServerSocketChannelImpl
|
|||
|
||||
// Our file descriptor
|
||||
private final FileDescriptor fd;
|
||||
|
||||
// fd value needed for dev/poll. This value will remain valid
|
||||
// even after the value in the file descriptor object has been set to -1
|
||||
private int fdVal;
|
||||
private final int fdVal;
|
||||
|
||||
// ID of native thread currently blocked in this channel, for signalling
|
||||
private volatile long thread;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2000, 2018, 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
|
||||
|
@ -25,10 +25,23 @@
|
|||
|
||||
package sun.nio.ch;
|
||||
|
||||
import java.io.*;
|
||||
import java.net.*;
|
||||
import java.nio.*;
|
||||
import java.nio.channels.*;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.net.InetAddress;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.Socket;
|
||||
import java.net.SocketAddress;
|
||||
import java.net.SocketException;
|
||||
import java.net.SocketImpl;
|
||||
import java.net.SocketOption;
|
||||
import java.net.SocketTimeoutException;
|
||||
import java.net.StandardSocketOptions;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.channels.Channels;
|
||||
import java.nio.channels.ClosedChannelException;
|
||||
import java.nio.channels.IllegalBlockingModeException;
|
||||
import java.nio.channels.SocketChannel;
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedExceptionAction;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
@ -45,7 +58,7 @@ import java.util.concurrent.TimeUnit;
|
|||
// java.net.Socket so as to simplify tracking future changes to that class.
|
||||
//
|
||||
|
||||
public class SocketAdaptor
|
||||
class SocketAdaptor
|
||||
extends Socket
|
||||
{
|
||||
|
||||
|
@ -89,7 +102,6 @@ public class SocketAdaptor
|
|||
throw new IllegalBlockingModeException();
|
||||
|
||||
try {
|
||||
|
||||
if (timeout == 0) {
|
||||
sc.connect(remote);
|
||||
return;
|
||||
|
@ -119,8 +131,9 @@ public class SocketAdaptor
|
|||
}
|
||||
}
|
||||
} finally {
|
||||
if (sc.isOpen())
|
||||
try {
|
||||
sc.configureBlocking(true);
|
||||
} catch (ClosedChannelException e) { }
|
||||
}
|
||||
|
||||
} catch (Exception x) {
|
||||
|
@ -188,10 +201,11 @@ public class SocketAdaptor
|
|||
synchronized (sc.blockingLock()) {
|
||||
if (!sc.isBlocking())
|
||||
throw new IllegalBlockingModeException();
|
||||
|
||||
if (timeout == 0)
|
||||
return sc.read(bb);
|
||||
sc.configureBlocking(false);
|
||||
|
||||
sc.configureBlocking(false);
|
||||
try {
|
||||
int n;
|
||||
if ((n = sc.read(bb)) != 0)
|
||||
|
@ -213,10 +227,10 @@ public class SocketAdaptor
|
|||
throw new SocketTimeoutException();
|
||||
}
|
||||
} finally {
|
||||
if (sc.isOpen())
|
||||
try {
|
||||
sc.configureBlocking(true);
|
||||
} catch (ClosedChannelException e) { }
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -68,9 +68,6 @@ class SocketChannelImpl
|
|||
|
||||
// Our file descriptor object
|
||||
private final FileDescriptor fd;
|
||||
|
||||
// fd value needed for dev/poll. This value will remain valid
|
||||
// even after the value in the file descriptor object has been set to -1
|
||||
private final int fdVal;
|
||||
|
||||
// IDs of native threads doing reads and writes, for signalling
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue