Skip to content

Commit 391bd2d

Browse files
committed
8309305: sun/security/ssl/SSLSocketImpl/BlockedAsyncClose.java fails with jtreg test timeout
Backport-of: 8042a50b99a671390910afa5f816894f77255429
1 parent e9ddb51 commit 391bd2d

File tree

1 file changed

+33
-37
lines changed

1 file changed

+33
-37
lines changed

test/jdk/sun/security/ssl/SSLSocketImpl/BlockedAsyncClose.java

Lines changed: 33 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2019, 2023, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -29,7 +29,8 @@
2929
/*
3030
* @test
3131
* @bug 8224829
32-
* @summary AsyncSSLSocketClose.java has timing issue
32+
* @summary AsyncSSLSocketClose.java has timing issue.
33+
* @library /javax/net/ssl/templates
3334
* @run main/othervm BlockedAsyncClose
3435
*/
3536

@@ -38,52 +39,41 @@
3839
import java.net.SocketException;
3940
import java.net.InetAddress;
4041
import java.net.InetSocketAddress;
42+
import java.util.Arrays;
4143
import java.util.concurrent.CountDownLatch;
4244
import java.util.concurrent.TimeUnit;
45+
import java.util.concurrent.locks.Lock;
46+
import java.util.concurrent.locks.ReentrantLock;
4347

44-
public class BlockedAsyncClose implements Runnable {
48+
/*
49+
* To manually verify that the write thread was blocked when socket.close() is called,
50+
* run the test with -Djavax.net.debug=ssl. You should see the message
51+
* "SSLSocket output duplex close failed: SO_LINGER timeout, close_notify message cannot be sent."
52+
*/
53+
public class BlockedAsyncClose extends SSLContextTemplate implements Runnable {
4554
SSLSocket socket;
4655
SSLServerSocket ss;
4756

4857
// Is the socket ready to close?
4958
private final CountDownLatch closeCondition = new CountDownLatch(1);
50-
51-
// Where do we find the keystores?
52-
static String pathToStores = "../../../../javax/net/ssl/etc";
53-
static String keyStoreFile = "keystore";
54-
static String trustStoreFile = "truststore";
55-
static String passwd = "passphrase";
59+
private final Lock writeLock = new ReentrantLock();
5660

5761
public static void main(String[] args) throws Exception {
58-
String keyFilename =
59-
System.getProperty("test.src", "./") + "/" + pathToStores +
60-
"/" + keyStoreFile;
61-
String trustFilename =
62-
System.getProperty("test.src", "./") + "/" + pathToStores +
63-
"/" + trustStoreFile;
64-
65-
System.setProperty("javax.net.ssl.keyStore", keyFilename);
66-
System.setProperty("javax.net.ssl.keyStorePassword", passwd);
67-
System.setProperty("javax.net.ssl.trustStore", trustFilename);
68-
System.setProperty("javax.net.ssl.trustStorePassword", passwd);
69-
70-
new BlockedAsyncClose();
62+
new BlockedAsyncClose().runTest();
7163
}
7264

73-
public BlockedAsyncClose() throws Exception {
74-
SSLServerSocketFactory sslssf =
75-
(SSLServerSocketFactory)SSLServerSocketFactory.getDefault();
65+
public void runTest() throws Exception {
66+
SSLServerSocketFactory sslssf = createServerSSLContext().getServerSocketFactory();
7667
InetAddress loopback = InetAddress.getLoopbackAddress();
7768
ss = (SSLServerSocket)sslssf.createServerSocket();
7869
ss.bind(new InetSocketAddress(loopback, 0));
7970

80-
SSLSocketFactory sslsf =
81-
(SSLSocketFactory)SSLSocketFactory.getDefault();
71+
SSLSocketFactory sslsf = createClientSSLContext().getSocketFactory();
8272
socket = (SSLSocket)sslsf.createSocket(loopback, ss.getLocalPort());
8373
SSLSocket serverSoc = (SSLSocket)ss.accept();
8474
ss.close();
8575

86-
(new Thread(this)).start();
76+
new Thread(this).start();
8777
serverSoc.startHandshake();
8878

8979
boolean closeIsReady = closeCondition.await(90L, TimeUnit.SECONDS);
@@ -94,23 +84,22 @@ public BlockedAsyncClose() throws Exception {
9484
}
9585

9686
socket.setSoLinger(true, 10);
97-
System.out.println("Calling Socket.close");
9887

99-
// Sleep for a while so that the write thread blocks by hitting the
100-
// output stream buffer limit.
101-
Thread.sleep(1000);
88+
// if the writeLock is not released by the other thread within 10
89+
// seconds it is probably blocked, and we can try to close the socket
90+
while (writeLock.tryLock(10, TimeUnit.SECONDS)) {
91+
writeLock.unlock();
92+
}
10293

94+
System.out.println("Calling socket.close()");
10395
socket.close();
104-
System.out.println("ssl socket get closed");
10596
System.out.flush();
10697
}
10798

10899
// block in write
109100
public void run() {
110101
byte[] ba = new byte[1024];
111-
for (int i = 0; i < ba.length; i++) {
112-
ba[i] = 0x7A;
113-
}
102+
Arrays.fill(ba, (byte) 0x7A);
114103

115104
try {
116105
OutputStream os = socket.getOutputStream();
@@ -128,8 +117,16 @@ public void run() {
128117
// write more
129118
while (true) {
130119
count += ba.length;
120+
131121
System.out.println(count + " bytes to be written");
122+
123+
writeLock.lock();
132124
os.write(ba);
125+
// This isn't in a try/finally. If an exception is thrown
126+
// and the lock is released, the main thread will
127+
// loop until the test times out. So don't release it.
128+
writeLock.unlock();
129+
133130
System.out.println(count + " bytes written");
134131
}
135132
} catch (SocketException se) {
@@ -144,4 +141,3 @@ public void run() {
144141
}
145142
}
146143
}
147-

0 commit comments

Comments
 (0)