Skip to content

Commit b7cbc6b

Browse files
committed
Release GIL in SSL socket operations
1 parent ff2d493 commit b7cbc6b

File tree

2 files changed

+25
-18
lines changed

2 files changed

+25
-18
lines changed

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ssl/PMemoryBIO.java

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -81,14 +81,15 @@ public ByteBuffer getBufferForReading() {
8181

8282
/**
8383
* Update read position from a buffer previously obtained using {@link #getBufferForReading()}
84-
* The caller is responsible for making sure the buffer was obtained for this BIO, that this BIO
85-
* was not concurrently updated since the {@link #getBufferForReading()} call and that the
86-
* position was not moved backwards.
84+
* The caller is responsible for making sure the buffer was obtained for this BIO and that the
85+
* position was not moved backwards. If the BIO was concurrently modified, the contents are
86+
* undefined, but the structure stays valid.
8787
*/
8888
public void applyRead(ByteBuffer buffer) {
89-
readPosition = buffer.position();
90-
assert buffer.array() == bytes;
91-
assert readPosition <= writePosition;
89+
if (buffer.array() == bytes) {
90+
readPosition = buffer.position();
91+
assert readPosition <= writePosition;
92+
}
9293
}
9394

9495
/**
@@ -104,14 +105,15 @@ public ByteBuffer getBufferForWriting() {
104105

105106
/**
106107
* Update write position from a buffer previously obtained using {@link #getBufferForWriting()}.
107-
* The caller is responsible for making sure the buffer was obtained for this BIO, that this BIO
108-
* was not concurrently updated since the {@link #getBufferForWriting()} call and that the
109-
* position was not moved backwards.
108+
* The caller is responsible for making sure the buffer was obtained for this BIO and that the
109+
* position was not moved backwards. If the BIO was concurrently modified, the contents are
110+
* undefined, but the structure stays valid.
110111
*/
111112
public void applyWrite(ByteBuffer buffer) {
112-
writePosition = buffer.position();
113-
assert buffer.array() == bytes;
114-
assert readPosition <= writePosition;
113+
if (buffer.array() == bytes) {
114+
writePosition = buffer.position();
115+
assert readPosition <= writePosition;
116+
}
115117
}
116118

117119
/**

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ssl/SSLEngineHelper.java

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@
5959
import com.oracle.graal.python.nodes.ErrorMessages;
6060
import com.oracle.graal.python.nodes.PNodeWithRaise;
6161
import com.oracle.graal.python.nodes.PRaiseNode;
62+
import com.oracle.graal.python.runtime.GilNode;
6263
import com.oracle.graal.python.runtime.exception.PException;
6364
import com.oracle.graal.python.util.OverflowException;
6465
import com.oracle.truffle.api.CompilerDirectives;
@@ -392,6 +393,7 @@ private static PException handleSSLException(PNodeWithRaise node, SSLException e
392393
throw PRaiseSSLErrorNode.raiseUncached(node, SSLErrorCode.ERROR_SSL, e.toString());
393394
}
394395

396+
@SuppressWarnings("try")
395397
private static int obtainMoreInput(PNodeWithRaise node, SSLEngine engine, PMemoryBIO networkInboundBIO, PSocket socket, TimeoutHelper timeoutHelper) throws IOException, OverflowException {
396398
if (socket != null) {
397399
if (socket.getSocket() == null) {
@@ -426,7 +428,7 @@ private static int obtainMoreInput(PNodeWithRaise node, SSLEngine engine, PMemor
426428
ByteBuffer writeBuffer = networkInboundBIO.getBufferForWriting();
427429
// Avoid reading more that we determined
428430
writeBuffer.limit(writeBuffer.position() + toRead);
429-
try {
431+
try (GilNode.UncachedRelease gil = GilNode.uncachedRelease()) {
430432
return SocketUtils.recv(node, socket, writeBuffer, timeoutHelper == null ? 0 : timeoutHelper.checkAndGetRemainingTimeout(node));
431433
} finally {
432434
networkInboundBIO.applyWrite(writeBuffer);
@@ -443,22 +445,25 @@ private static int obtainMoreInput(PNodeWithRaise node, SSLEngine engine, PMemor
443445
}
444446
}
445447

448+
@SuppressWarnings("try")
446449
private static void emitOutputOrRaiseWantWrite(PNodeWithRaise node, PMemoryBIO networkOutboundBIO, PSocket socket, TimeoutHelper timeoutHelper) throws IOException {
447450
if (socket != null && networkOutboundBIO.getPending() > 0) {
448451
if (socket.getSocket() == null) {
449452
// TODO use raiseOsError with ENOTCONN
450453
throw node.raise(OSError);
451454
}
455+
int pendingBytes = networkOutboundBIO.getPending();
452456
// Network output
453457
ByteBuffer readBuffer = networkOutboundBIO.getBufferForReading();
454-
try {
455-
int writtenBytes = SocketUtils.send(node, socket, readBuffer, timeoutHelper == null ? 0 : timeoutHelper.checkAndGetRemainingTimeout(node));
456-
if (writtenBytes == 0) {
457-
throw PRaiseSSLErrorNode.raiseUncached(node, SSLErrorCode.ERROR_WANT_WRITE, ErrorMessages.SSL_WANT_WRITE);
458-
}
458+
int writtenBytes;
459+
try (GilNode.UncachedRelease gil = GilNode.uncachedRelease()) {
460+
writtenBytes = SocketUtils.send(node, socket, readBuffer, timeoutHelper == null ? 0 : timeoutHelper.checkAndGetRemainingTimeout(node));
459461
} finally {
460462
networkOutboundBIO.applyRead(readBuffer);
461463
}
464+
if (writtenBytes < pendingBytes) {
465+
throw PRaiseSSLErrorNode.raiseUncached(node, SSLErrorCode.ERROR_WANT_WRITE, ErrorMessages.SSL_WANT_WRITE);
466+
}
462467
}
463468
}
464469
}

0 commit comments

Comments
 (0)