8358764: (sc) SocketChannel.close when thread blocked in read causes connection to be reset (win)
I backport this for parity with 17.0.18-oracle.
Needed resolve and adaptions:
Net.java: resolved static initializer. SocketChannelImpl.java: In implCloseBlockingMode(), the code guarded by the new condition is not in 17. Omitted. Update: I added this later.
Net.c: Copyright.
The test exercises platform and virtual threads. I simplified this to what is supported in 17. See extra commit.
Progress
- [x] Change must be properly reviewed (1 review required, with at least 1 Reviewer)
- [x] Change must not contain extraneous whitespace
- [x] Commit message must refer to an issue
- [ ] JDK-8358764 needs maintainer approval
Issue
- JDK-8358764: (sc) SocketChannel.close when thread blocked in read causes connection to be reset (win) (Bug - P3 - Requested)
Reviewers
- Martin Doerr (@TheRealMDoerr - Reviewer)
Reviewing
Using git
Checkout this PR locally:
$ git fetch https://git.openjdk.org/jdk17u-dev.git pull/4076/head:pull/4076
$ git checkout pull/4076
Update a local copy of the PR:
$ git checkout pull/4076
$ git pull https://git.openjdk.org/jdk17u-dev.git pull/4076/head
Using Skara CLI tools
Checkout this PR locally:
$ git pr checkout 4076
View PR using the GUI difftool:
$ git pr show -t 4076
Using diff file
Download this PR as a diff file:
https://git.openjdk.org/jdk17u-dev/pull/4076.diff
Using Webrev
:wave: Welcome back goetz! 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.
@GoeLin This change now passes all automated pre-integration checks.
ℹ️ This project also has non-automated pre-integration requirements. Please see the file CONTRIBUTING.md for details.
After integration, the commit message for the final commit will be:
8358764: (sc) SocketChannel.close when thread blocked in read causes connection to be reset (win)
Reviewed-by: mdoerr
You can use pull request commands such as /summary, /contributor and /issue to adjust it as needed.
At the time when this comment was updated there had been 24 new commits pushed to the master branch:
- 9bf2571e7bc9d8752e0c10fcde4973df2f7688ea: 8328299: Convert DnDFileGroupDescriptor.html applet test to main
- 9592af7835d267307e43b5a54abe46c519d746c3: 8352686: Opensource JInternalFrame tests - series3
- 943251d93719fef24e973a0a6a75e204f223d0a7: 8357822: C2: Multiple string optimization tests are no longer testing string concatenation optimizations
- ... and 21 more: https://git.openjdk.org/jdk17u-dev/compare/846d334b983774d803395c15c499faccc0bbf1b4...master
As there are no conflicts, your changes will automatically be rebased on top of these commits when integrating. If you prefer to avoid this automatic rebasing, please check the documentation for the /integrate command for further details.
➡️ To integrate this PR with the above commit message to the master branch, type /integrate in a new comment.
This backport pull request has now been updated with issue from the original commit.
Webrevs
- 05: Full - Incremental (e97dccc0)
- 04: Full - Incremental (6692163a)
- 03: Full - Incremental (c16a2c8e)
- 02: Full - Incremental (58cce4b1)
- 01: Full - Incremental (bdb4707e)
- 00: Full (d57767e8)
It is true that the affected part of implCloseBlockingMode() has been introduced with Loom, but it looks relevant without Loom, too. Note that implCloseNonBlockingMode() handles StandardSocketOptions.SO_LINGER, too.
Without this change, your PR basically only adds a test because shouldShutdownWriteBeforeClose() is unused.
diff --git a/src/java.base/share/classes/sun/nio/ch/SocketChannelImpl.java b/src/java.base/share/classes/sun/nio/ch/SocketChannelImpl.java
index a771d998b24..09c9ed4df99 100644
--- a/src/java.base/share/classes/sun/nio/ch/SocketChannelImpl.java
+++ b/src/java.base/share/classes/sun/nio/ch/SocketChannelImpl.java
@@ -1019,7 +1019,19 @@ class SocketChannelImpl
private void implCloseBlockingMode() throws IOException {
synchronized (stateLock) {
assert state < ST_CLOSING;
+ boolean connected = (state == ST_CONNECTED);
state = ST_CLOSING;
+
+ if (connected && Net.shouldShutdownWriteBeforeClose()) {
+ // shutdown output when linger interval not set to 0
+ try {
+ var SO_LINGER = StandardSocketOptions.SO_LINGER;
+ if ((int) Net.getSocketOption(fd, SO_LINGER) != 0) {
+ Net.shutdown(fd, Net.SHUT_WR);
+ }
+ } catch (IOException ignore) { }
+ }
+
if (!tryClose()) {
long reader = readerThread;
long writer = writerThread;
⚠️ @GoeLin This change is now ready for you to apply for maintainer approval. This can be done directly in each associated issue or by using the /approval command.
Hi @AlanBateman and Kieran Farrell,
do you mind having a look at this? The code patched by the original change in SocketChannelImpl.java is not in 17. Do you think it is ok to include this in 17 along with this change? It seems to be a fix independent of the loom change that added it.
Thanks! Goetz.
Hi @AlanBateman and Kieran Farrell,
do you mind having a look at this? The code patched by the original change in SocketChannelImpl.java is not in 17. Do you think it is ok to include this in 17 along with this change? It seems to be a fix independent of the loom change that added it.
From a quick look then it seems okay. In sun.nio.ch.Net then shutdownWriteBeforeClose can be eagerly or lazily initialized, you've chosen to do it lazily which is okay.
The split of the blocking/non-blocking code paths had several motivations, the issue is specific to the (less common) case of using a SocketChannel blocking mode so I think you've got it right.
Hi @AlanBateman, thanks for having a look!
@GoeLin btw, it seems the introduced test passes always. I ran it with jtreg on windows arm without the fix in place. Did I run it incorrectly? 🤔
@GoeLin btw, it seems the introduced test passes always. I ran it with jtreg on windows arm without the fix in place. Did I run it incorrectly? 🤔
Does the test from https://github.com/openjdk/jdk21u-dev/pull/2137 always fail in jdk21u without the fix? I guess that the problem is better reproducible with loom. Ah, I can see that your test in https://github.com/openjdk/jdk17u-dev/pull/3936 is different. Can it reproduce the issue better?
@GoeLin btw, it seems the introduced test passes always. I ran it with jtreg on windows arm without the fix in place. Did I run it incorrectly? 🤔
Does the test from openjdk/jdk21u-dev#2137 always fail in jdk21u without the fix? I guess that the problem is better reproducible with loom. Ah, I can see that your test in #3936 is different. Can it reproduce the issue better?
@TheRealMDoerr for me, it's reproducible with the test from my PR.
Hi @antonvoznia , I will run the test without the fix through our testing, let's see whether it reproduces the issue.
Hi @antonvoznia, yes, we obviously need the setDeamon(true) you added in your test. This makes the test fail without the fix. I add the differences to your test if you don't mind.
/integrate
Going to push as commit e3c50e1b14afde0d02d8d39b3ae8569c97d1855b.
Since your change was applied there have been 24 commits pushed to the master branch:
- 9bf2571e7bc9d8752e0c10fcde4973df2f7688ea: 8328299: Convert DnDFileGroupDescriptor.html applet test to main
- 9592af7835d267307e43b5a54abe46c519d746c3: 8352686: Opensource JInternalFrame tests - series3
- 943251d93719fef24e973a0a6a75e204f223d0a7: 8357822: C2: Multiple string optimization tests are no longer testing string concatenation optimizations
- ... and 21 more: https://git.openjdk.org/jdk17u-dev/compare/846d334b983774d803395c15c499faccc0bbf1b4...master
Your commit was automatically rebased without conflicts.
@GoeLin Pushed as commit e3c50e1b14afde0d02d8d39b3ae8569c97d1855b.
:bulb: You may see a message that your pull request was closed with unmerged commits. This can be safely ignored.