annotate src/windows/native/sun/nio/ch/SocketChannelImpl.c @ 594:14f50aee4989

6754988: Update copyright year Summary: Update for files that have been modified starting July 2008 Reviewed-by: ohair, tbell
author xdono
date Thu, 02 Oct 2008 19:58:32 -0700
parents 343253d05123
children 00cd9dc3c2b5
rev   line source
duke@0 1 /*
xdono@594 2 * Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved.
duke@0 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
duke@0 4 *
duke@0 5 * This code is free software; you can redistribute it and/or modify it
duke@0 6 * under the terms of the GNU General Public License version 2 only, as
duke@0 7 * published by the Free Software Foundation. Sun designates this
duke@0 8 * particular file as subject to the "Classpath" exception as provided
duke@0 9 * by Sun in the LICENSE file that accompanied this code.
duke@0 10 *
duke@0 11 * This code is distributed in the hope that it will be useful, but WITHOUT
duke@0 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
duke@0 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
duke@0 14 * version 2 for more details (a copy is included in the LICENSE file that
duke@0 15 * accompanied this code).
duke@0 16 *
duke@0 17 * You should have received a copy of the GNU General Public License version
duke@0 18 * 2 along with this work; if not, write to the Free Software Foundation,
duke@0 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
duke@0 20 *
duke@0 21 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
duke@0 22 * CA 95054 USA or visit www.sun.com if you need additional information or
duke@0 23 * have any questions.
duke@0 24 */
duke@0 25
duke@0 26 #include <windows.h>
duke@0 27 #include <winsock2.h>
duke@0 28 #include <ctype.h>
duke@0 29 #include "jni.h"
duke@0 30 #include "jni_util.h"
duke@0 31 #include "jvm.h"
duke@0 32 #include "jlong.h"
duke@0 33 #include "sun_nio_ch_SocketChannelImpl.h"
duke@0 34
duke@0 35 #include "nio.h"
duke@0 36 #include "nio_util.h"
duke@0 37 #include "net_util.h"
duke@0 38
duke@0 39
duke@0 40 static jfieldID ia_addrID; /* java.net.InetAddress.address */
duke@0 41
duke@0 42 JNIEXPORT void JNICALL
duke@0 43 Java_sun_nio_ch_SocketChannelImpl_initIDs(JNIEnv *env, jclass cls)
duke@0 44 {
duke@0 45 cls = (*env)->FindClass(env, "java/net/InetAddress");
duke@0 46 ia_addrID = (*env)->GetFieldID(env, cls, "address", "I");
duke@0 47 }
duke@0 48
duke@0 49 jint
duke@0 50 handleSocketError(JNIEnv *env, int errorValue)
duke@0 51 {
duke@0 52 NET_ThrowNew(env, errorValue, NULL);
duke@0 53 return IOS_THROWN;
duke@0 54 }
duke@0 55
duke@0 56 JNIEXPORT jint JNICALL
duke@0 57 Java_sun_nio_ch_SocketChannelImpl_checkConnect(JNIEnv *env, jobject this,
duke@0 58 jobject fdo, jboolean block,
duke@0 59 jboolean ready)
duke@0 60 {
duke@0 61 int optError = 0;
duke@0 62 int lastError = 0;
duke@0 63 int result = 0;
duke@0 64 int retry = 0;
duke@0 65 int n = sizeof(int);
duke@0 66 jint fd = fdval(env, fdo);
duke@0 67 fd_set wr, ex;
duke@0 68 struct timeval t = { 0, 0 };
duke@0 69
duke@0 70 FD_ZERO(&wr);
duke@0 71 FD_ZERO(&ex);
duke@0 72 FD_SET((u_int)fd, &wr);
duke@0 73 FD_SET((u_int)fd, &ex);
duke@0 74
duke@0 75 result = select(fd+1, 0, &wr, &ex, block ? NULL : &t);
duke@0 76
duke@0 77 /* save last winsock error */
duke@0 78 if (result == SOCKET_ERROR) {
duke@0 79 lastError = WSAGetLastError();
duke@0 80 }
duke@0 81
duke@0 82 if (block) { /* must configure socket back to blocking state */
duke@0 83 u_long argp = 0;
duke@0 84 int r = ioctlsocket(fd, FIONBIO, &argp);
duke@0 85 if (r == SOCKET_ERROR) {
duke@0 86 handleSocketError(env, WSAGetLastError());
duke@0 87 }
duke@0 88 }
duke@0 89
duke@0 90 if (result == 0) { /* timeout */
duke@0 91 return block ? 0 : IOS_UNAVAILABLE;
duke@0 92 } else {
duke@0 93 if (result == SOCKET_ERROR) { /* select failed */
duke@0 94 handleSocketError(env, lastError);
duke@0 95 return IOS_THROWN;
duke@0 96 }
duke@0 97 }
duke@0 98
duke@0 99 /*
duke@0 100 * Socket is writable or error occured. On some Windows editions
duke@0 101 * the socket will appear writable when the connect fails so we
duke@0 102 * check for error rather than writable.
duke@0 103 */
duke@0 104 if (!FD_ISSET(fd, &ex)) {
duke@0 105 return 1; /* connection established */
duke@0 106 }
duke@0 107
duke@0 108 /*
duke@0 109 * A getsockopt( SO_ERROR ) may indicate success on NT4 even
duke@0 110 * though the connection has failed. The workaround is to allow
duke@0 111 * winsock to be scheduled and this is done via by yielding.
duke@0 112 * As the yield approach is problematic in heavy load situations
duke@0 113 * we attempt up to 3 times to get the failure reason.
duke@0 114 */
duke@0 115 for (retry=0; retry<3; retry++) {
duke@0 116 result = getsockopt((SOCKET)fd,
duke@0 117 SOL_SOCKET,
duke@0 118 SO_ERROR,
duke@0 119 (char *)&optError,
duke@0 120 &n);
duke@0 121 if (result == SOCKET_ERROR) {
duke@0 122 int lastError = WSAGetLastError();
duke@0 123 if (lastError == WSAEINPROGRESS) {
duke@0 124 return IOS_UNAVAILABLE;
duke@0 125 }
duke@0 126 NET_ThrowNew(env, lastError, "getsockopt");
duke@0 127 return IOS_THROWN;
duke@0 128 }
duke@0 129 if (optError) {
duke@0 130 break;
duke@0 131 }
duke@0 132 Sleep(0);
duke@0 133 }
duke@0 134
duke@0 135 if (optError != NO_ERROR) {
duke@0 136 handleSocketError(env, optError);
duke@0 137 return IOS_THROWN;
duke@0 138 }
duke@0 139
duke@0 140 return 0;
duke@0 141 }