< prev index next >

src/java.base/windows/native/libnet/TwoStacksPlainDatagramSocketImpl.c

Print this page
rev 53271 : 8216981: Per thread IO statistics in JFR


 420  */
 421 JNIEXPORT void JNICALL
 422 Java_java_net_TwoStacksPlainDatagramSocketImpl_send
 423   (JNIEnv *env, jobject this, jobject packet)
 424 {
 425     char BUF[MAX_BUFFER_LEN];
 426     char *fullPacket;
 427     jobject fdObj;
 428     jint fd;
 429 
 430     jobject iaObj;
 431     jint family;
 432 
 433     jint packetBufferOffset, packetBufferLen, packetPort;
 434     jbyteArray packetBuffer;
 435     jboolean connected;
 436 
 437     SOCKETADDRESS rmtaddr;
 438     struct sockaddr *addrp = 0;
 439     int addrlen = 0;

 440 
 441     if (IS_NULL(packet)) {
 442         JNU_ThrowNullPointerException(env, "null packet");
 443         return;
 444     }
 445 
 446     iaObj = (*env)->GetObjectField(env, packet, dp_addressID);
 447 
 448     packetPort = (*env)->GetIntField(env, packet, dp_portID);
 449     packetBufferOffset = (*env)->GetIntField(env, packet, dp_offsetID);
 450     packetBuffer = (jbyteArray)(*env)->GetObjectField(env, packet, dp_bufID);
 451     connected = (*env)->GetBooleanField(env, this, pdsi_connected);
 452 
 453     if (IS_NULL(iaObj) || IS_NULL(packetBuffer)) {
 454         JNU_ThrowNullPointerException(env, "null address || null buffer");
 455         return;
 456     }
 457 
 458     family = getInetAddress_family(env, iaObj);
 459     JNU_CHECK_EXCEPTION(env);


 498          * than 2048 bytes into several operations of size 2048.
 499          * This saves a malloc()/memcpy()/free() for big
 500          * buffers.  This is OK for file IO and TCP, but that
 501          * strategy violates the semantics of a datagram protocol.
 502          * (one big send) != (several smaller sends).  So here
 503          * we *must* alloc the buffer.  Note it needn't be bigger
 504          * than 65,536 (0xFFFF) the max size of an IP packet.
 505          * anything bigger is truncated anyway.
 506          */
 507         fullPacket = (char *)malloc(packetBufferLen);
 508         if (!fullPacket) {
 509             JNU_ThrowOutOfMemoryError(env, "Send buf native heap allocation failed");
 510             return;
 511         }
 512     } else {
 513         fullPacket = &(BUF[0]);
 514     }
 515 
 516     (*env)->GetByteArrayRegion(env, packetBuffer, packetBufferOffset,
 517                                packetBufferLen, (jbyte *)fullPacket);
 518     if (sendto(fd, fullPacket, packetBufferLen, 0, addrp,
 519                addrlen) == SOCKET_ERROR)
 520     {
 521         NET_ThrowCurrent(env, "Datagram send failed");
 522     }
 523 




 524     if (packetBufferLen > MAX_BUFFER_LEN) {
 525         free(fullPacket);
 526     }
 527 }
 528 
 529 /*
 530  * check which socket was last serviced when there was data on both sockets.
 531  * Only call this if sure that there is data on both sockets.
 532  */
 533 static int checkLastFD (JNIEnv *env, jobject this, int fd, int fd1) {
 534     int nextfd, lastfd = (*env)->GetIntField(env, this, pdsi_lastfdID);
 535     if (lastfd == -1) {
 536         /* arbitrary. Choose fd */
 537         (*env)->SetIntField(env, this, pdsi_lastfdID, fd);
 538         return fd;
 539     } else {
 540         if (lastfd == fd) {
 541             nextfd = fd1;
 542         } else {
 543             nextfd = fd;


1140                             JNU_ThrowByName(env, JNU_JAVANETPKG "SocketTimeoutException",
1141                                             "Receive timed out");
1142                         } else if (ret == -1) {
1143                             JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
1144                                             "Socket closed");
1145                         }
1146                         if (packetBufferLen > MAX_BUFFER_LEN) {
1147                             free(fullPacket);
1148                         }
1149                         return;
1150                     }
1151                 }
1152 
1153                 /*
1154                  * An ICMP port unreachable was received but we are
1155                  * not connected so ignore it.
1156                  */
1157                 retry = TRUE;
1158             }
1159         }



1160     } while (retry);
1161 
1162     /* truncate the data if the packet's length is too small */
1163     if (n > packetBufferLen) {
1164         n = packetBufferLen;
1165     }
1166     if (n < 0) {
1167         errorCode = WSAGetLastError();
1168         /* check to see if it's because the buffer was too small */
1169         if (errorCode == WSAEMSGSIZE) {
1170             /* it is because the buffer is too small. It's UDP, it's
1171              * unreliable, it's all good. discard the rest of the
1172              * data..
1173              */
1174             n = packetBufferLen;
1175         } else {
1176             /* failure */
1177             (*env)->SetIntField(env, packet, dp_lengthID, 0);
1178         }
1179     }




 420  */
 421 JNIEXPORT void JNICALL
 422 Java_java_net_TwoStacksPlainDatagramSocketImpl_send
 423   (JNIEnv *env, jobject this, jobject packet)
 424 {
 425     char BUF[MAX_BUFFER_LEN];
 426     char *fullPacket;
 427     jobject fdObj;
 428     jint fd;
 429 
 430     jobject iaObj;
 431     jint family;
 432 
 433     jint packetBufferOffset, packetBufferLen, packetPort;
 434     jbyteArray packetBuffer;
 435     jboolean connected;
 436 
 437     SOCKETADDRESS rmtaddr;
 438     struct sockaddr *addrp = 0;
 439     int addrlen = 0;
 440     int ret;
 441 
 442     if (IS_NULL(packet)) {
 443         JNU_ThrowNullPointerException(env, "null packet");
 444         return;
 445     }
 446 
 447     iaObj = (*env)->GetObjectField(env, packet, dp_addressID);
 448 
 449     packetPort = (*env)->GetIntField(env, packet, dp_portID);
 450     packetBufferOffset = (*env)->GetIntField(env, packet, dp_offsetID);
 451     packetBuffer = (jbyteArray)(*env)->GetObjectField(env, packet, dp_bufID);
 452     connected = (*env)->GetBooleanField(env, this, pdsi_connected);
 453 
 454     if (IS_NULL(iaObj) || IS_NULL(packetBuffer)) {
 455         JNU_ThrowNullPointerException(env, "null address || null buffer");
 456         return;
 457     }
 458 
 459     family = getInetAddress_family(env, iaObj);
 460     JNU_CHECK_EXCEPTION(env);


 499          * than 2048 bytes into several operations of size 2048.
 500          * This saves a malloc()/memcpy()/free() for big
 501          * buffers.  This is OK for file IO and TCP, but that
 502          * strategy violates the semantics of a datagram protocol.
 503          * (one big send) != (several smaller sends).  So here
 504          * we *must* alloc the buffer.  Note it needn't be bigger
 505          * than 65,536 (0xFFFF) the max size of an IP packet.
 506          * anything bigger is truncated anyway.
 507          */
 508         fullPacket = (char *)malloc(packetBufferLen);
 509         if (!fullPacket) {
 510             JNU_ThrowOutOfMemoryError(env, "Send buf native heap allocation failed");
 511             return;
 512         }
 513     } else {
 514         fullPacket = &(BUF[0]);
 515     }
 516 
 517     (*env)->GetByteArrayRegion(env, packetBuffer, packetBufferOffset,
 518                                packetBufferLen, (jbyte *)fullPacket);
 519     if (ret = sendto(fd, fullPacket, packetBufferLen, 0, addrp,
 520                addrlen) == SOCKET_ERROR)
 521     {
 522         NET_ThrowCurrent(env, "Datagram send failed");
 523     }
 524 
 525     if (ret > 0) {
 526       JVM_callFileWriteBytes(env, ret);
 527     }
 528 
 529     if (packetBufferLen > MAX_BUFFER_LEN) {
 530         free(fullPacket);
 531     }
 532 }
 533 
 534 /*
 535  * check which socket was last serviced when there was data on both sockets.
 536  * Only call this if sure that there is data on both sockets.
 537  */
 538 static int checkLastFD (JNIEnv *env, jobject this, int fd, int fd1) {
 539     int nextfd, lastfd = (*env)->GetIntField(env, this, pdsi_lastfdID);
 540     if (lastfd == -1) {
 541         /* arbitrary. Choose fd */
 542         (*env)->SetIntField(env, this, pdsi_lastfdID, fd);
 543         return fd;
 544     } else {
 545         if (lastfd == fd) {
 546             nextfd = fd1;
 547         } else {
 548             nextfd = fd;


1145                             JNU_ThrowByName(env, JNU_JAVANETPKG "SocketTimeoutException",
1146                                             "Receive timed out");
1147                         } else if (ret == -1) {
1148                             JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
1149                                             "Socket closed");
1150                         }
1151                         if (packetBufferLen > MAX_BUFFER_LEN) {
1152                             free(fullPacket);
1153                         }
1154                         return;
1155                     }
1156                 }
1157 
1158                 /*
1159                  * An ICMP port unreachable was received but we are
1160                  * not connected so ignore it.
1161                  */
1162                 retry = TRUE;
1163             }
1164         }
1165         if (n > 0) {
1166             JVM_callNetworkReadBytes(env, n);
1167         }
1168     } while (retry);
1169 
1170     /* truncate the data if the packet's length is too small */
1171     if (n > packetBufferLen) {
1172         n = packetBufferLen;
1173     }
1174     if (n < 0) {
1175         errorCode = WSAGetLastError();
1176         /* check to see if it's because the buffer was too small */
1177         if (errorCode == WSAEMSGSIZE) {
1178             /* it is because the buffer is too small. It's UDP, it's
1179              * unreliable, it's all good. discard the rest of the
1180              * data..
1181              */
1182             n = packetBufferLen;
1183         } else {
1184             /* failure */
1185             (*env)->SetIntField(env, packet, dp_lengthID, 0);
1186         }
1187     }


< prev index next >