Skip to content

Commit fa2a5af

Browse files
Merge pull request #230 from cconlon/deadlockFixes
JSSE: fix deadlock issues between SSLSocket close() and OutputStream write()
2 parents 30e4042 + fe40fe7 commit fa2a5af

1 file changed

Lines changed: 81 additions & 63 deletions

File tree

src/java/com/wolfssl/provider/jsse/WolfSSLSocket.java

Lines changed: 81 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -1937,18 +1937,16 @@ public synchronized void close() throws IOException {
19371937
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
19381938
"thread got ioLock (shutdown)");
19391939

1940-
synchronized (handshakeLock) {
1941-
if (this.getUseClientMode() == true &&
1942-
this.handshakeComplete == true) {
1943-
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
1944-
"saving WOLFSSL_SESSION into cache");
1945-
EngineHelper.saveSession();
1946-
}
1947-
else {
1948-
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
1949-
"not saving WOLFSSL_SESSION into cache, " +
1950-
"not client or handshake not complete");
1951-
}
1940+
if ((this.getUseClientMode() == true) &&
1941+
(handshakeFinished == true)) {
1942+
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
1943+
"saving WOLFSSL_SESSION into cache");
1944+
EngineHelper.saveSession();
1945+
}
1946+
else {
1947+
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
1948+
"not saving WOLFSSL_SESSION into cache, " +
1949+
"not client or handshake not complete");
19521950
}
19531951

19541952
try {
@@ -2001,26 +1999,32 @@ public synchronized void close() throws IOException {
20011999
this.EngineHelper.clearObjectState();
20022000
this.EngineHelper = null;
20032001

2004-
/* Release Input/OutputStream objects. Do not
2005-
* close WolfSSLSocket inside stream close,
2006-
* since we handle that next below and do
2007-
* differently depending on if autoClose has been
2008-
* set or not. */
2009-
if (this.inStream != null) {
2010-
this.inStream.close(false);
2011-
this.inStream = null;
2012-
}
2013-
if (this.outStream != null) {
2014-
this.outStream.close(false);
2015-
this.outStream = null;
2016-
}
2002+
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
2003+
"thread exiting handshakeLock (shutdown)");
20172004

20182005
} /* handshakeLock */
20192006

20202007
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
20212008
"thread exiting ioLock (shutdown)");
20222009

20232010
} /* ioLock */
2011+
2012+
/* Release Input/OutputStream objects. Do not close
2013+
* WolfSSLSocket inside stream close, since we handle that
2014+
* next below and do differently depending on if autoClose
2015+
* has been set or not. */
2016+
if (this.inStream != null) {
2017+
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
2018+
"close(), closing InputStream");
2019+
this.inStream.close(false);
2020+
this.inStream = null;
2021+
}
2022+
if (this.outStream != null) {
2023+
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
2024+
"close(), closing OutputStream");
2025+
this.outStream.close(false);
2026+
this.outStream = null;
2027+
}
20242028
}
20252029
}
20262030

@@ -2457,27 +2461,28 @@ protected void close(boolean closeSocket) throws IOException {
24572461

24582462
if (isClosing.compareAndSet(false, true)) {
24592463

2460-
synchronized (this) {
2461-
if (closeSocket) {
2462-
if (this.socket == null || this.isClosed) {
2463-
return;
2464-
}
2465-
2466-
if (this.socket.isClosed()) {
2467-
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
2468-
"socket (input) already closed");
2469-
}
2470-
else {
2471-
this.socket.close();
2472-
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
2473-
"socket (input) closed: " + this.socket);
2474-
}
2464+
if (closeSocket) {
2465+
if (this.socket == null || this.isClosed) {
2466+
return;
24752467
}
24762468

2477-
this.socket = null;
2478-
this.ssl = null;
2479-
this.isClosed = true;
2469+
if (this.socket.isClosed()) {
2470+
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
2471+
"socket (input) already closed");
2472+
}
2473+
else {
2474+
this.socket.close();
2475+
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
2476+
"socket (input) closed: " + this.socket);
2477+
}
24802478
}
2479+
2480+
this.socket = null;
2481+
this.ssl = null;
2482+
this.isClosed = true;
2483+
2484+
/* Reset "is closing" state to false, now closed */
2485+
isClosing.set(false);
24812486
}
24822487
else {
24832488
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
@@ -2534,6 +2539,12 @@ public synchronized int read(byte[] b, int off, int len)
25342539
throw new NullPointerException("Input array is null");
25352540
}
25362541

2542+
/* check if socket is closing */
2543+
if (isClosing.get()) {
2544+
throw new SocketException(
2545+
"InputStream in process of being closed");
2546+
}
2547+
25372548
/* check if socket is closed */
25382549
if (this.isClosed || socket == null || socket.isClosed()) {
25392550
throw new SocketException("Socket is closed");
@@ -2670,27 +2681,28 @@ protected void close(boolean closeSocket) throws IOException {
26702681

26712682
if (isClosing.compareAndSet(false, true)) {
26722683

2673-
synchronized (this) {
2674-
if (closeSocket) {
2675-
if (this.socket == null || this.isClosed) {
2676-
return;
2677-
}
2678-
2679-
if (this.socket.isClosed()) {
2680-
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
2681-
"socket (output) already closed");
2682-
}
2683-
else {
2684-
this.socket.close();
2685-
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
2686-
"socket (output) closed: " + this.socket);
2687-
}
2684+
if (closeSocket) {
2685+
if (this.socket == null || this.isClosed) {
2686+
return;
26882687
}
26892688

2690-
this.socket = null;
2691-
this.ssl = null;
2692-
this.isClosed = true;
2689+
if (this.socket.isClosed()) {
2690+
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
2691+
"socket (output) already closed");
2692+
}
2693+
else {
2694+
this.socket.close();
2695+
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
2696+
"socket (output) closed: " + this.socket);
2697+
}
26932698
}
2699+
2700+
this.socket = null;
2701+
this.ssl = null;
2702+
this.isClosed = true;
2703+
2704+
/* Reset "is closing" state to false, now closed */
2705+
isClosing.set(false);
26942706
}
26952707
else {
26962708
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
@@ -2707,14 +2719,14 @@ public void close() throws IOException {
27072719
this.close(true);
27082720
}
27092721

2710-
public synchronized void write(int b) throws IOException {
2722+
public void write(int b) throws IOException {
27112723
byte[] data = new byte[1];
27122724
data[0] = (byte)(b & 0xFF);
27132725

27142726
this.write(data, 0, 1);
27152727
}
27162728

2717-
public synchronized void write(byte[] b) throws IOException {
2729+
public void write(byte[] b) throws IOException {
27182730
this.write(b, 0, b.length);
27192731
}
27202732

@@ -2727,6 +2739,12 @@ public synchronized void write(byte[] b, int off, int len)
27272739
throw new NullPointerException("Input array is null");
27282740
}
27292741

2742+
/* check if socket is closing */
2743+
if (isClosing.get()) {
2744+
throw new SocketException(
2745+
"OutputStream in process of being closed");
2746+
}
2747+
27302748
/* check if socket is closed */
27312749
if (this.isClosed || socket == null || socket.isClosed()) {
27322750
throw new SocketException("Socket is closed");

0 commit comments

Comments
 (0)