8267564: JDK-8252971 causes SPECjbb2015 socket exceptions on Windows when MKS is installed

Reviewed-by: alanb
This commit is contained in:
Michael McMahon 2021-06-08 07:58:54 +00:00
parent 00c88f79b3
commit 61ab4b9d18
3 changed files with 68 additions and 10 deletions
src/java.base
share/classes/sun/nio/ch
unix/native/libnio/ch
windows/native/libnio/ch

@ -160,7 +160,7 @@ class UnixDomainSockets {
return n;
}
private static native boolean socketSupported();
private static native boolean init();
private static native int socket0() throws IOException;
@ -176,6 +176,6 @@ class UnixDomainSockets {
static {
// Load all required native libs
IOUtil.load();
supported = socketSupported();
supported = init();
}
}

@ -95,7 +95,7 @@ jint unixSocketAddressToSockaddr(JNIEnv *env, jbyteArray path, struct sockaddr_u
}
JNIEXPORT jboolean JNICALL
Java_sun_nio_ch_UnixDomainSockets_socketSupported(JNIEnv *env, jclass cl)
Java_sun_nio_ch_UnixDomainSockets_init(JNIEnv *env, jclass cl)
{
return JNI_TRUE;
}

@ -38,6 +38,9 @@
#include "sun_nio_ch_Net.h"
#include "sun_nio_ch_PollArrayWrapper.h"
/* The winsock provider ID of the Microsoft AF_UNIX implementation */
static GUID MS_PROVIDER_ID = {0xA00943D9,0x9C2E,0x4633,{0x9B,0x59,0,0x57,0xA3,0x16,0x09,0x94}};
jbyteArray sockaddrToUnixAddressBytes(JNIEnv *env, struct sockaddr_un *sa, socklen_t len)
{
if (sa->sun_family == AF_UNIX) {
@ -84,21 +87,76 @@ jint unixSocketAddressToSockaddr(JNIEnv *env, jbyteArray addr, struct sockaddr_u
return ret;
}
JNIEXPORT jboolean JNICALL
Java_sun_nio_ch_UnixDomainSockets_socketSupported(JNIEnv *env, jclass cl)
{
SOCKET s = socket(PF_UNIX, SOCK_STREAM, 0);
if (s == INVALID_SOCKET) {
static int cmpGuid(GUID *g1, GUID *g2) {
if (g1->Data1 != g2->Data1)
return JNI_FALSE;
if (g1->Data2 != g2->Data2)
return JNI_FALSE;
if (g1->Data3 != g2->Data3)
return JNI_FALSE;
for (int i=0; i<8; i++) {
if (g1->Data4[i] != g2->Data4[i])
return JNI_FALSE;
}
closesocket(s);
return JNI_TRUE;
}
static WSAPROTOCOL_INFOW provider;
JNIEXPORT jboolean JNICALL
Java_sun_nio_ch_UnixDomainSockets_init(JNIEnv *env, jclass cl)
{
WSAPROTOCOL_INFOW info[5]; // if not large enough, a buffer is malloc'd
LPWSAPROTOCOL_INFOW infoPtr = &info[0];
DWORD len = sizeof(info);
jboolean found = JNI_FALSE;
/*
* First locate the Microsoft AF_UNIX Winsock provider
*/
int result = WSAEnumProtocolsW(0, infoPtr, &len);
if (result == SOCKET_ERROR) {
if (GetLastError() == WSAENOBUFS) {
infoPtr = (LPWSAPROTOCOL_INFOW)malloc(len);
result = WSAEnumProtocolsW(0, infoPtr, &len);
if (result == SOCKET_ERROR) {
free(infoPtr);
return JNI_FALSE;
}
} else {
return JNI_FALSE;
}
}
for (int i=0; i<result; i++) {
if (infoPtr[i].iAddressFamily == AF_UNIX) {
GUID g = infoPtr[i].ProviderId;
if (cmpGuid(&g, &MS_PROVIDER_ID)) {
found = JNI_TRUE;
provider = infoPtr[i];
break;
}
}
}
if (infoPtr != &info[0]) {
free(infoPtr);
}
/*
* check we can create a socket
*/
if (found) {
SOCKET s = WSASocketW(PF_UNIX, SOCK_STREAM, 0, &provider, 0, WSA_FLAG_OVERLAPPED);
if (s == INVALID_SOCKET) {
return JNI_FALSE;
}
closesocket(s);
}
return found;
}
JNIEXPORT jint JNICALL
Java_sun_nio_ch_UnixDomainSockets_socket0(JNIEnv *env, jclass cl)
{
SOCKET s = socket(PF_UNIX, SOCK_STREAM, 0);
SOCKET s = WSASocketW(PF_UNIX, SOCK_STREAM, 0, &provider, 0, WSA_FLAG_OVERLAPPED);
if (s == INVALID_SOCKET) {
return handleSocketError(env, WSAGetLastError());
}