8200304: TwoStacksPlainDatagramSocketImpl and socket cleaner
Reviewed-by: alanb, dfuchs, rriggs
--- a/src/java.base/windows/classes/java/net/TwoStacksPlainDatagramSocketImpl.java Thu Mar 29 08:52:41 2018 -0700
+++ b/src/java.base/windows/classes/java/net/TwoStacksPlainDatagramSocketImpl.java Thu Mar 29 20:12:02 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2007, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 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
@@ -40,7 +40,7 @@
* @author Chris Hegarty
*/
-class TwoStacksPlainDatagramSocketImpl extends AbstractPlainDatagramSocketImpl
+final class TwoStacksPlainDatagramSocketImpl extends AbstractPlainDatagramSocketImpl
{
/* Used for IPv6 on Windows only */
private FileDescriptor fd1;
@@ -105,8 +105,16 @@
protected synchronized void bind0(int lport, InetAddress laddr)
throws SocketException
{
+ // The native bind0 may close one or both of the underlying file
+ // descriptors, and even create new sockets, so the safest course of
+ // action is to unregister the socket cleaners, and register afterwards.
+ SocketCleanable.unregister(fd);
+ SocketCleanable.unregister(fd1);
+
bind0(lport, laddr, exclusiveBind);
+ SocketCleanable.register(fd);
+ SocketCleanable.register(fd1);
}
protected synchronized void receive(DatagramPacket p)
--- a/src/java.base/windows/native/libnet/TwoStacksPlainDatagramSocketImpl.c Thu Mar 29 08:52:41 2018 -0700
+++ b/src/java.base/windows/native/libnet/TwoStacksPlainDatagramSocketImpl.c Thu Mar 29 20:12:02 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -491,7 +491,9 @@
if (WSAGetLastError() == WSAEACCES) {
WSASetLastError(WSAEADDRINUSE);
}
+ (*env)->SetObjectField(env, this, pdsi_fdID, NULL);
NET_ThrowCurrent(env, "Cannot bind");
+ closesocket(fd);
return;
}
}