Skip to content

Commit 214f8a3

Browse files
committed
Use non-blocking connections, but retry as if blocking
We want to have blocking operations, but we can't hold the GVL, so we'll emulate blocking operations by calling the non-blocking API, then call io_waitreadable
1 parent 4ba604a commit 214f8a3

1 file changed

Lines changed: 24 additions & 6 deletions

File tree

ext/openssl/ossl_ssl.c

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2879,11 +2879,20 @@ static VALUE
28792879
ossl_ssl_accept_stream(VALUE self)
28802880
{
28812881
SSL *ssl, *stream_ssl;
2882+
VALUE io = rb_attr_get(self, id_i_io);
28822883

28832884
GetSSL(self, ssl);
2884-
stream_ssl = SSL_accept_stream(ssl, 0);
2885-
if (!stream_ssl)
2886-
ossl_raise(eSSLError, "SSL_accept_stream");
2885+
2886+
/*
2887+
* Use NO_BLOCK flag and retry in a loop. We treat any NULL return as
2888+
* "not ready" and wait for the socket to become readable, rather than
2889+
* checking SSL_get_error(), because SSL_get_error() returns incorrect
2890+
* error codes for SSL_accept_stream (it stalls instead of returning a
2891+
* retryable error).
2892+
*/
2893+
while ((stream_ssl = SSL_accept_stream(ssl, SSL_ACCEPT_STREAM_NO_BLOCK)) == NULL) {
2894+
io_wait_readable(io);
2895+
}
28872896

28882897
return ossl_ssl_wrap_stream(self, stream_ssl);
28892898
}
@@ -3146,11 +3155,20 @@ static VALUE
31463155
ossl_ssl_accept_connection(VALUE self)
31473156
{
31483157
SSL *ssl, *conn_ssl;
3158+
VALUE io = rb_attr_get(self, id_i_io);
31493159

31503160
GetSSL(self, ssl);
3151-
conn_ssl = SSL_accept_connection(ssl, 0);
3152-
if (!conn_ssl)
3153-
ossl_raise(eSSLError, "SSL_accept_connection");
3161+
3162+
/*
3163+
* Use NO_BLOCK flag and retry in a loop. We treat any NULL return as
3164+
* "not ready" and wait for the socket to become readable, rather than
3165+
* checking SSL_get_error(), because SSL_get_error() returns incorrect
3166+
* error codes for SSL_accept_connection (it returns "conn use only"
3167+
* instead of a retryable error).
3168+
*/
3169+
while ((conn_ssl = SSL_accept_connection(ssl, SSL_ACCEPT_CONNECTION_NO_BLOCK)) == NULL) {
3170+
io_wait_readable(io);
3171+
}
31543172

31553173
return ossl_ssl_wrap_connection(self, conn_ssl);
31563174
}

0 commit comments

Comments
 (0)