Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/windows/native/sun/nio/ch/SocketDispatcher.c
32288 views
/*1* Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425#include <windows.h>26#include <winsock2.h>27#include <ctype.h>28#include "jni.h"29#include "jni_util.h"30#include "jvm.h"31#include "jlong.h"32#include "sun_nio_ch_SocketDispatcher.h"33#include "nio.h"34#include "nio_util.h"353637/**************************************************************38* SocketDispatcher.c39*/4041JNIEXPORT jint JNICALL42Java_sun_nio_ch_SocketDispatcher_read0(JNIEnv *env, jclass clazz, jobject fdo,43jlong address, jint len)44{45/* set up */46int i = 0;47DWORD read = 0;48DWORD flags = 0;49jint fd = fdval(env, fdo);50WSABUF buf;5152/* limit size */53if (len > MAX_BUFFER_SIZE)54len = MAX_BUFFER_SIZE;5556/* destination buffer and size */57buf.buf = (char *)address;58buf.len = (u_long)len;5960/* read into the buffers */61i = WSARecv((SOCKET)fd, /* Socket */62&buf, /* pointers to the buffers */63(DWORD)1, /* number of buffers to process */64&read, /* receives number of bytes read */65&flags, /* no flags */660, /* no overlapped sockets */670); /* no completion routine */6869if (i == SOCKET_ERROR) {70int theErr = (jint)WSAGetLastError();71if (theErr == WSAEWOULDBLOCK) {72return IOS_UNAVAILABLE;73}74JNU_ThrowIOExceptionWithLastError(env, "Read failed");75return IOS_THROWN;76}7778return convertReturnVal(env, (jint)read, JNI_TRUE);79}8081JNIEXPORT jlong JNICALL82Java_sun_nio_ch_SocketDispatcher_readv0(JNIEnv *env, jclass clazz, jobject fdo,83jlong address, jint len)84{85/* set up */86int i = 0;87DWORD read = 0;88DWORD flags = 0;89jint fd = fdval(env, fdo);90struct iovec *iovp = (struct iovec *)address;91WSABUF *bufs = malloc(len * sizeof(WSABUF));92jint rem = MAX_BUFFER_SIZE;9394if (bufs == 0) {95JNU_ThrowOutOfMemoryError(env, 0);96return IOS_THROWN;97}9899/* copy iovec into WSABUF */100for(i=0; i<len; i++) {101jint iov_len = iovp[i].iov_len;102if (iov_len > rem)103iov_len = rem;104bufs[i].buf = (char *)iovp[i].iov_base;105bufs[i].len = (u_long)iov_len;106rem -= iov_len;107if (rem == 0) {108len = i+1;109break;110}111}112113/* read into the buffers */114i = WSARecv((SOCKET)fd, /* Socket */115bufs, /* pointers to the buffers */116(DWORD)len, /* number of buffers to process */117&read, /* receives number of bytes read */118&flags, /* no flags */1190, /* no overlapped sockets */1200); /* no completion routine */121122/* clean up */123free(bufs);124125if (i != 0) {126int theErr = (jint)WSAGetLastError();127if (theErr == WSAEWOULDBLOCK) {128return IOS_UNAVAILABLE;129}130JNU_ThrowIOExceptionWithLastError(env, "Vector read failed");131return IOS_THROWN;132}133134return convertLongReturnVal(env, (jlong)read, JNI_TRUE);135}136137JNIEXPORT jint JNICALL138Java_sun_nio_ch_SocketDispatcher_write0(JNIEnv *env, jclass clazz, jobject fdo,139jlong address, jint total)140{141/* set up */142int i = 0;143DWORD written = 0;144jint count = 0;145jint fd = fdval(env, fdo);146WSABUF buf;147148do {149/* limit size */150jint len = total - count;151if (len > MAX_BUFFER_SIZE)152len = MAX_BUFFER_SIZE;153154/* copy iovec into WSABUF */155buf.buf = (char *)address;156buf.len = (u_long)len;157158/* write from the buffer */159i = WSASend((SOCKET)fd, /* Socket */160&buf, /* pointers to the buffers */161(DWORD)1, /* number of buffers to process */162&written, /* receives number of bytes written */1630, /* no flags */1640, /* no overlapped sockets */1650); /* no completion routine */166167if (i == SOCKET_ERROR) {168if (count > 0) {169/* can't throw exception when some bytes have been written */170break;171} else {172int theErr = (jint)WSAGetLastError();173if (theErr == WSAEWOULDBLOCK) {174return IOS_UNAVAILABLE;175}176JNU_ThrowIOExceptionWithLastError(env, "Write failed");177return IOS_THROWN;178}179}180181count += written;182address += written;183184} while ((count < total) && (written == MAX_BUFFER_SIZE));185186return count;187}188189JNIEXPORT jlong JNICALL190Java_sun_nio_ch_SocketDispatcher_writev0(JNIEnv *env, jclass clazz,191jobject fdo, jlong address, jint len)192{193/* set up */194int next_index, next_offset, ret=0;195DWORD written = 0;196jint fd = fdval(env, fdo);197struct iovec *iovp = (struct iovec *)address;198WSABUF *bufs = malloc(len * sizeof(WSABUF));199jlong count = 0;200201if (bufs == 0) {202JNU_ThrowOutOfMemoryError(env, 0);203return IOS_THROWN;204}205206// next buffer and offset to consume207next_index = 0;208next_offset = 0;209210while (next_index < len) {211DWORD buf_count = 0;212213/* Prepare the WSABUF array to a maximum total size of MAX_BUFFER_SIZE */214jint rem = MAX_BUFFER_SIZE;215while (next_index < len && rem > 0) {216jint iov_len = iovp[next_index].iov_len - next_offset;217char* ptr = (char *)iovp[next_index].iov_base;218ptr += next_offset;219if (iov_len > rem) {220iov_len = rem;221next_offset += rem;222} else {223next_index ++;224next_offset = 0;225}226227bufs[buf_count].buf = ptr;228bufs[buf_count].len = (u_long)iov_len;229buf_count++;230231rem -= iov_len;232}233234/* write the buffers */235ret = WSASend((SOCKET)fd, /* Socket */236bufs, /* pointers to the buffers */237buf_count, /* number of buffers to process */238&written, /* receives number of bytes written */2390, /* no flags */2400, /* no overlapped sockets */2410); /* no completion routine */242243if (ret == SOCKET_ERROR) {244break;245}246247count += written;248}249250/* clean up */251free(bufs);252253if (ret == SOCKET_ERROR && count == 0) {254int theErr = (jint)WSAGetLastError();255if (theErr == WSAEWOULDBLOCK) {256return IOS_UNAVAILABLE;257}258JNU_ThrowIOExceptionWithLastError(env, "Vector write failed");259return IOS_THROWN;260}261262return convertLongReturnVal(env, count, JNI_FALSE);263}264265JNIEXPORT void JNICALL266Java_sun_nio_ch_SocketDispatcher_preClose0(JNIEnv *env, jclass clazz,267jobject fdo)268{269jint fd = fdval(env, fdo);270struct linger l;271int len = sizeof(l);272if (getsockopt(fd, SOL_SOCKET, SO_LINGER, (char *)&l, &len) == 0) {273if (l.l_onoff == 0) {274WSASendDisconnect(fd, NULL);275}276}277}278279JNIEXPORT void JNICALL280Java_sun_nio_ch_SocketDispatcher_close0(JNIEnv *env, jclass clazz,281jobject fdo)282{283jint fd = fdval(env, fdo);284if (closesocket(fd) == SOCKET_ERROR) {285JNU_ThrowIOExceptionWithLastError(env, "Socket close failed");286}287}288289290