mirror of
https://github.com/openjdk/jdk.git
synced 2025-09-23 20:44:41 +02:00
6621689: (dc spec) DatagramChannel.receive when channel is not bound is not specified
Reviewed-by: sherman
This commit is contained in:
parent
4654daefa2
commit
6af949fe24
3 changed files with 114 additions and 24 deletions
|
@ -261,7 +261,10 @@ public abstract class DatagramChannel
|
||||||
*
|
*
|
||||||
* <p> This method may be invoked at any time. It will not have any effect
|
* <p> This method may be invoked at any time. It will not have any effect
|
||||||
* on read or write operations that are already in progress at the moment
|
* on read or write operations that are already in progress at the moment
|
||||||
* that it is invoked. </p>
|
* that it is invoked. If this channel's socket is not bound then this method
|
||||||
|
* will first cause the socket to be bound to an address that is assigned
|
||||||
|
* automatically, as if invoking the {@link #bind bind} method with a
|
||||||
|
* parameter of {@code null}. </p>
|
||||||
*
|
*
|
||||||
* @param remote
|
* @param remote
|
||||||
* The remote address to which this channel is to be connected
|
* The remote address to which this channel is to be connected
|
||||||
|
@ -356,7 +359,10 @@ public abstract class DatagramChannel
|
||||||
* <p> This method may be invoked at any time. If another thread has
|
* <p> This method may be invoked at any time. If another thread has
|
||||||
* already initiated a read operation upon this channel, however, then an
|
* already initiated a read operation upon this channel, however, then an
|
||||||
* invocation of this method will block until the first operation is
|
* invocation of this method will block until the first operation is
|
||||||
* complete. </p>
|
* complete. If this channel's socket is not bound then this method will
|
||||||
|
* first cause the socket to be bound to an address that is assigned
|
||||||
|
* automatically, as if invoking the {@link #bind bind} method with a
|
||||||
|
* parameter of {@code null}. </p>
|
||||||
*
|
*
|
||||||
* @param dst
|
* @param dst
|
||||||
* The buffer into which the datagram is to be transferred
|
* The buffer into which the datagram is to be transferred
|
||||||
|
@ -413,7 +419,10 @@ public abstract class DatagramChannel
|
||||||
* <p> This method may be invoked at any time. If another thread has
|
* <p> This method may be invoked at any time. If another thread has
|
||||||
* already initiated a write operation upon this channel, however, then an
|
* already initiated a write operation upon this channel, however, then an
|
||||||
* invocation of this method will block until the first operation is
|
* invocation of this method will block until the first operation is
|
||||||
* complete. </p>
|
* complete. If this channel's socket is not bound then this method will
|
||||||
|
* first cause the socket to be bound to an address that is assigned
|
||||||
|
* automatically, as if by invoking the {@link #bind bind) method with a
|
||||||
|
* parameter of {@code null}. </p>
|
||||||
*
|
*
|
||||||
* @param src
|
* @param src
|
||||||
* The buffer containing the datagram to be sent
|
* The buffer containing the datagram to be sent
|
||||||
|
|
|
@ -313,11 +313,9 @@ class DatagramChannelImpl
|
||||||
throw new NullPointerException();
|
throw new NullPointerException();
|
||||||
synchronized (readLock) {
|
synchronized (readLock) {
|
||||||
ensureOpen();
|
ensureOpen();
|
||||||
// If socket is not bound then behave as if nothing received
|
// Socket was not bound before attempting receive
|
||||||
// Will be fixed by 6621699
|
if (localAddress() == null)
|
||||||
if (localAddress() == null) {
|
bind(null);
|
||||||
return null;
|
|
||||||
}
|
|
||||||
int n = 0;
|
int n = 0;
|
||||||
ByteBuffer bb = null;
|
ByteBuffer bb = null;
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -22,27 +22,110 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* @test
|
/* @test
|
||||||
* @bug 4512723
|
* @bug 4512723 6621689
|
||||||
* @summary Unit test for datagram-socket-channel adaptors
|
* @summary Test that connect/send/receive with unbound DatagramChannel causes
|
||||||
|
* the channel's socket to be bound to a local address
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import java.net.*;
|
import java.net.*;
|
||||||
import java.nio.*;
|
import java.nio.ByteBuffer;
|
||||||
import java.nio.channels.*;
|
import java.nio.channels.DatagramChannel;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
class NotBound {
|
public class NotBound {
|
||||||
public static void main(String[] args) throws Exception {
|
|
||||||
test1(false);
|
static void checkBound(DatagramChannel dc) throws IOException {
|
||||||
test1(true);
|
if (dc.getLocalAddress() == null)
|
||||||
|
throw new RuntimeException("Not bound??");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void test1(boolean blocking) throws Exception {
|
// starts a thread to send a datagram to the given channel once the channel
|
||||||
ByteBuffer bb = ByteBuffer.allocateDirect(256);
|
// is bound to a local address
|
||||||
DatagramChannel dc1 = DatagramChannel.open();
|
static void wakeupWhenBound(final DatagramChannel dc) {
|
||||||
dc1.configureBlocking(false);
|
Runnable wakeupTask = new Runnable() {
|
||||||
SocketAddress isa = dc1.receive(bb);
|
public void run() {
|
||||||
if (isa != null)
|
try {
|
||||||
throw new Exception("Unbound dc returned non-null");
|
// poll for local address
|
||||||
dc1.close();
|
InetSocketAddress local;
|
||||||
|
do {
|
||||||
|
Thread.sleep(50);
|
||||||
|
local = (InetSocketAddress)dc.getLocalAddress();
|
||||||
|
} while (local == null);
|
||||||
|
|
||||||
|
// send message to channel to wakeup receiver
|
||||||
|
DatagramChannel sender = DatagramChannel.open();
|
||||||
|
try {
|
||||||
|
ByteBuffer bb = ByteBuffer.wrap("hello".getBytes());
|
||||||
|
InetAddress lh = InetAddress.getLocalHost();
|
||||||
|
SocketAddress target =
|
||||||
|
new InetSocketAddress(lh, local.getPort());
|
||||||
|
sender.send(bb, target);
|
||||||
|
} finally {
|
||||||
|
sender.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (Exception x) {
|
||||||
|
x.printStackTrace();
|
||||||
|
}
|
||||||
|
}};
|
||||||
|
new Thread(wakeupTask).start();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) throws IOException {
|
||||||
|
DatagramChannel dc;
|
||||||
|
|
||||||
|
// connect
|
||||||
|
dc = DatagramChannel.open();
|
||||||
|
try {
|
||||||
|
DatagramChannel peer = DatagramChannel.open()
|
||||||
|
.bind(new InetSocketAddress(0));
|
||||||
|
int peerPort = ((InetSocketAddress)(peer.getLocalAddress())).getPort();
|
||||||
|
try {
|
||||||
|
dc.connect(new InetSocketAddress(InetAddress.getLocalHost(), peerPort));
|
||||||
|
checkBound(dc);
|
||||||
|
} finally {
|
||||||
|
peer.close();
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
dc.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
// send
|
||||||
|
dc = DatagramChannel.open();
|
||||||
|
try {
|
||||||
|
ByteBuffer bb = ByteBuffer.wrap("ignore this".getBytes());
|
||||||
|
SocketAddress target =
|
||||||
|
new InetSocketAddress(InetAddress.getLocalHost(), 5000);
|
||||||
|
dc.send(bb, target);
|
||||||
|
checkBound(dc);
|
||||||
|
} finally {
|
||||||
|
dc.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
// receive (blocking)
|
||||||
|
dc = DatagramChannel.open();
|
||||||
|
try {
|
||||||
|
ByteBuffer bb = ByteBuffer.allocateDirect(128);
|
||||||
|
wakeupWhenBound(dc);
|
||||||
|
SocketAddress sender = dc.receive(bb);
|
||||||
|
if (sender == null)
|
||||||
|
throw new RuntimeException("Sender should not be null");
|
||||||
|
checkBound(dc);
|
||||||
|
} finally {
|
||||||
|
dc.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
// receive (non-blocking)
|
||||||
|
dc = DatagramChannel.open();
|
||||||
|
try {
|
||||||
|
dc.configureBlocking(false);
|
||||||
|
ByteBuffer bb = ByteBuffer.allocateDirect(128);
|
||||||
|
SocketAddress sender = dc.receive(bb);
|
||||||
|
if (sender != null)
|
||||||
|
throw new RuntimeException("Sender should be null");
|
||||||
|
checkBound(dc);
|
||||||
|
} finally {
|
||||||
|
dc.close();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue