613 socklen_t slen = sizeof(SOCKETADDRESS);
614
615 if (IS_NULL(fdObj)) {
616 JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
617 "Socket closed");
618 return;
619 } else {
620 fd = (*env)->GetIntField(env, fdObj, IO_fd_fdID);
621 }
622 if (IS_NULL(socket)) {
623 JNU_ThrowNullPointerException(env, "socket is null");
624 return;
625 }
626
627 /*
628 * accept connection but ignore ECONNABORTED indicating that
629 * connection was eagerly accepted by the OS but was reset
630 * before accept() was called.
631 *
632 * If accept timeout in place and timeout is adjusted with
633 * each ECONNABORTED or EWOULDBLOCK to ensure that semantics
634 * of timeout are preserved.
635 */
636 for (;;) {
637 int ret;
638 jlong currNanoTime;
639
640 /* first usage pick up current time */
641 if (prevNanoTime == 0 && nanoTimeout > 0) {
642 prevNanoTime = JVM_NanoTime(env, 0);
643 }
644
645 /* passing a timeout of 0 to poll will return immediately,
646 but in the case of ServerSocket 0 means infinite. */
647 if (timeout <= 0) {
648 ret = NET_Timeout(env, fd, -1, 0);
649 } else {
650 ret = NET_Timeout(env, fd, nanoTimeout / NET_NSEC_PER_MSEC, prevNanoTime);
651 }
652 if (ret == 0) {
653 JNU_ThrowByName(env, JNU_JAVANETPKG "SocketTimeoutException",
654 "Accept timed out");
656 } else if (ret == -1) {
657 if (errno == EBADF) {
658 JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", "Socket closed");
659 } else if (errno == ENOMEM) {
660 JNU_ThrowOutOfMemoryError(env, "NET_Timeout native heap allocation failed");
661 } else {
662 JNU_ThrowByNameWithMessageAndLastError
663 (env, JNU_JAVANETPKG "SocketException", "Accept failed");
664 }
665 return;
666 }
667
668 newfd = NET_Accept(fd, &sa.sa, &slen);
669
670 /* connection accepted */
671 if (newfd >= 0) {
672 SET_BLOCKING(newfd);
673 break;
674 }
675
676 /* non (ECONNABORTED or EWOULDBLOCK) error */
677 if (!(errno == ECONNABORTED || errno == EWOULDBLOCK)) {
678 break;
679 }
680
681 /* ECONNABORTED or EWOULDBLOCK error so adjust timeout if there is one. */
682 if (nanoTimeout >= NET_NSEC_PER_MSEC) {
683 currNanoTime = JVM_NanoTime(env, 0);
684 nanoTimeout -= (currNanoTime - prevNanoTime);
685 if (nanoTimeout < NET_NSEC_PER_MSEC) {
686 JNU_ThrowByName(env, JNU_JAVANETPKG "SocketTimeoutException",
687 "Accept timed out");
688 return;
689 }
690 prevNanoTime = currNanoTime;
691 }
692 }
693
694 if (newfd < 0) {
695 if (newfd == -2) {
696 JNU_ThrowByName(env, JNU_JAVAIOPKG "InterruptedIOException",
697 "operation interrupted");
698 } else {
699 if (errno == EINVAL) {
700 errno = EBADF;
701 }
|
613 socklen_t slen = sizeof(SOCKETADDRESS);
614
615 if (IS_NULL(fdObj)) {
616 JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
617 "Socket closed");
618 return;
619 } else {
620 fd = (*env)->GetIntField(env, fdObj, IO_fd_fdID);
621 }
622 if (IS_NULL(socket)) {
623 JNU_ThrowNullPointerException(env, "socket is null");
624 return;
625 }
626
627 /*
628 * accept connection but ignore ECONNABORTED indicating that
629 * connection was eagerly accepted by the OS but was reset
630 * before accept() was called.
631 *
632 * If accept timeout in place and timeout is adjusted with
633 * each ECONNABORTED or EWOULDBLOCK or EAGAIN to ensure that
634 * semantics of timeout are preserved.
635 */
636 for (;;) {
637 int ret;
638 jlong currNanoTime;
639
640 /* first usage pick up current time */
641 if (prevNanoTime == 0 && nanoTimeout > 0) {
642 prevNanoTime = JVM_NanoTime(env, 0);
643 }
644
645 /* passing a timeout of 0 to poll will return immediately,
646 but in the case of ServerSocket 0 means infinite. */
647 if (timeout <= 0) {
648 ret = NET_Timeout(env, fd, -1, 0);
649 } else {
650 ret = NET_Timeout(env, fd, nanoTimeout / NET_NSEC_PER_MSEC, prevNanoTime);
651 }
652 if (ret == 0) {
653 JNU_ThrowByName(env, JNU_JAVANETPKG "SocketTimeoutException",
654 "Accept timed out");
656 } else if (ret == -1) {
657 if (errno == EBADF) {
658 JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", "Socket closed");
659 } else if (errno == ENOMEM) {
660 JNU_ThrowOutOfMemoryError(env, "NET_Timeout native heap allocation failed");
661 } else {
662 JNU_ThrowByNameWithMessageAndLastError
663 (env, JNU_JAVANETPKG "SocketException", "Accept failed");
664 }
665 return;
666 }
667
668 newfd = NET_Accept(fd, &sa.sa, &slen);
669
670 /* connection accepted */
671 if (newfd >= 0) {
672 SET_BLOCKING(newfd);
673 break;
674 }
675
676 /* non (ECONNABORTED or EWOULDBLOCK or EAGAIN) error */
677 if (!(errno == ECONNABORTED || errno == EWOULDBLOCK || errno == EAGAIN)) {
678 break;
679 }
680
681 /* ECONNABORTED or EWOULDBLOCK or EAGAIN error so adjust timeout if there is one. */
682 if (nanoTimeout >= NET_NSEC_PER_MSEC) {
683 currNanoTime = JVM_NanoTime(env, 0);
684 nanoTimeout -= (currNanoTime - prevNanoTime);
685 if (nanoTimeout < NET_NSEC_PER_MSEC) {
686 JNU_ThrowByName(env, JNU_JAVANETPKG "SocketTimeoutException",
687 "Accept timed out");
688 return;
689 }
690 prevNanoTime = currNanoTime;
691 }
692 }
693
694 if (newfd < 0) {
695 if (newfd == -2) {
696 JNU_ThrowByName(env, JNU_JAVAIOPKG "InterruptedIOException",
697 "operation interrupted");
698 } else {
699 if (errno == EINVAL) {
700 errno = EBADF;
701 }
|