Skip to content

Commit b610717

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 596b4cf commit b610717

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
@@ -2875,11 +2875,20 @@ static VALUE
28752875
ossl_ssl_accept_stream(VALUE self)
28762876
{
28772877
SSL *ssl, *stream_ssl;
2878+
VALUE io = rb_attr_get(self, id_i_io);
28782879

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

28842893
return ossl_ssl_wrap_stream(self, stream_ssl);
28852894
}
@@ -3142,11 +3151,20 @@ static VALUE
31423151
ossl_ssl_accept_connection(VALUE self)
31433152
{
31443153
SSL *ssl, *conn_ssl;
3154+
VALUE io = rb_attr_get(self, id_i_io);
31453155

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

31513169
return ossl_ssl_wrap_connection(self, conn_ssl);
31523170
}

0 commit comments

Comments
 (0)