Skip to content

Conversation

@Michael-Mc-Mahon
Copy link
Member

@Michael-Mc-Mahon Michael-Mc-Mahon commented Dec 10, 2025

Hi,

This change updates the use of NET_ThrowNew in Inet4AddressImpl.c + Inet6AddressImpl.c (unix).
Currently EINTR is incorrectly handled in NET_ThrowNew to throw InterruptedIOException.

The only possible places in these files where EINTR can be returned is in the sendto() calls
for ping4() and ping6() used by the InetAddress.isReachable() API.

The change checks for EINTR returned from those calls and restarts the sendto()
if the timeout allows it. If EINTR is detected by NET_ThrowNew it is thrown as an ordinary
SocketException, but this should not happen.

The fix is only partially tested as it is difficult to make sendto() return EINTR in practice, but
I added a unit test for the new native function that checks if the timeout has expired.

Thanks,
Michael


Progress

  • Change must be properly reviewed (1 review required, with at least 1 Reviewer)
  • Change must not contain extraneous whitespace
  • Commit message must refer to an issue

Issue

  • JDK-8370655: Check EINTR handling InetAddress implementation and NET_ThrowNew (Bug - P4)

Reviewing

Using git

Checkout this PR locally:
$ git fetch https://git.openjdk.org/jdk.git pull/28750/head:pull/28750
$ git checkout pull/28750

Update a local copy of the PR:
$ git checkout pull/28750
$ git pull https://git.openjdk.org/jdk.git pull/28750/head

Using Skara CLI tools

Checkout this PR locally:
$ git pr checkout 28750

View PR using the GUI difftool:
$ git pr show -t 28750

Using diff file

Download this PR as a diff file:
https://git.openjdk.org/jdk/pull/28750.diff

Using Webrev

Link to Webrev Comment

@bridgekeeper
Copy link

bridgekeeper bot commented Dec 10, 2025

👋 Welcome back michaelm! A progress list of the required criteria for merging this PR into master will be added to the body of your pull request. There are additional pull request commands available for use with this pull request.

@openjdk
Copy link

openjdk bot commented Dec 10, 2025

❗ This change is not yet ready to be integrated.
See the Progress checklist in the description for automated requirements.

@openjdk
Copy link

openjdk bot commented Dec 10, 2025

@Michael-Mc-Mahon The following label will be automatically applied to this pull request:

  • net

When this pull request is ready to be reviewed, an "RFR" email will be sent to the corresponding mailing list. If you would like to change these labels, use the /label pull request command.

@openjdk openjdk bot added the rfr Pull request is ready for review label Dec 10, 2025
@mlbridge
Copy link

mlbridge bot commented Dec 10, 2025

Webrevs

icmp->icmp_cksum = in_cksum((u_short *)icmp, plen);
// send it
n = sendto(fd, sendbuf, plen, 0, &sa->sa, sizeof(struct sockaddr_in));
while (1) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are you sure it is possible for sendto to block indefinitely here? Maybe EINTR is possible but I think it would be okay to retry unconditionally, meaning I don't think timerMillisExpired is needed here.

Are you sure that we restart for the other blocking syscalls (poll, recvfrom, ...) in these methods?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oops. Didn't notice I had left the other calls out. Will add them now.

As for sendto() it's a lot less likely to block and I doubt it can block indefinitely, but I imagine it can block if socket buffer is full. I don't have a strong preference. If EINTR can be returned maybe it should be handled the same way?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As for sendto() it's a lot less likely to block and I doubt it can block indefinitely, but I imagine it can block if socket buffer is full. I don't have a strong preference. If EINTR can be returned maybe it should be handled the same way?

Hard to test but I suspect the packet will be dropped rather than blocking. So my guess is that retry here can be simple and doesn't need to use the timeout.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

getaddrinfo() and getnameinfo() can potentially return EINTR. The main blocking call in these files is NET_Wait, which is already restarting in the case of EINTR (along with all other errno values). The question is should we be returning an error if errno is not EINTR?

@Michael-Mc-Mahon Michael-Mc-Mahon marked this pull request as draft December 11, 2025 11:50
@openjdk openjdk bot removed the rfr Pull request is ready for review label Dec 11, 2025
@Michael-Mc-Mahon Michael-Mc-Mahon marked this pull request as ready for review December 11, 2025 16:23
@Michael-Mc-Mahon
Copy link
Member Author

I’ve updated the implementation to check for EINTR from all blocking calls and all other system calls specified to be able to return EINTR, though in all cases they are used in non-blocking mode, which means the error is unlikely to occur. The new native function is removed and the test that exercised it also.

There is some reformatting of NET_Wait but no functional changes.

@openjdk openjdk bot added the rfr Pull request is ready for review label Dec 11, 2025

error = getaddrinfo(hostname, NULL, &hints, &res);
NET_RESTARTABLE(error, getaddrinfo(hostname, NULL, &hints, &res),
error != EAI_SYSTEM)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Have you verified that a pthread_kill of a thread blocked in getaddrinfo returns EAI_SYSTEM with errno=EINTR? I can't be sure from the man page.

Copy link
Member Author

@Michael-Mc-Mahon Michael-Mc-Mahon Dec 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Have you verified that a pthread_kill of a thread blocked in getaddrinfo returns EAI_SYSTEM with errno=EINTR? I can't be sure from the man page.

I will try to verify that.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

net [email protected] rfr Pull request is ready for review

Development

Successfully merging this pull request may close these issues.

2 participants