* [PATCH] openssl: avoid kwarg parsing from C API at startup
@ 2015-12-02 0:11 Eric Wong
0 siblings, 0 replies; only message in thread
From: Eric Wong @ 2015-12-02 0:11 UTC (permalink / raw)
To: spew
Benchmarks coming...
---
ext/openssl/lib/openssl/ssl.rb | 48 ++++++++++++++++++++
ext/openssl/ossl_ssl.c | 101 ++++++++++++++---------------------------
2 files changed, 81 insertions(+), 68 deletions(-)
diff --git a/ext/openssl/lib/openssl/ssl.rb b/ext/openssl/lib/openssl/ssl.rb
index d3ae155..b273173 100644
--- a/ext/openssl/lib/openssl/ssl.rb
+++ b/ext/openssl/lib/openssl/ssl.rb
@@ -322,6 +322,54 @@ def session
nil
end
+ # call-seq:
+ # ssl.accept_nonblock([options]) => self
+ #
+ # Initiates the SSL/TLS handshake as a server in non-blocking manner.
+ #
+ # # emulates blocking accept
+ # begin
+ # ssl.accept_nonblock
+ # rescue IO::WaitReadable
+ # IO.select([s2])
+ # retry
+ # rescue IO::WaitWritable
+ # IO.select(nil, [s2])
+ # retry
+ # end
+ #
+ # By specifying `exception: false`, the options hash allows you to
+ # indicate that accept_nonblock should not raise an IO::WaitReadable or
+ # IO::WaitWritable exception, but return the symbol :wait_readable or
+ # :wait_writable instead.
+ def accept_nonblock(exception: true)
+ __accept_nonblock(exception)
+ end
+
+ # call-seq:
+ # ssl.connect_nonblock([options]) => self
+ #
+ # Initiates the SSL/TLS handshake as a client in non-blocking manner.
+ #
+ # # emulates blocking connect
+ # begin
+ # ssl.connect_nonblock
+ # rescue IO::WaitReadable
+ # IO.select([s2])
+ # retry
+ # rescue IO::WaitWritable
+ # IO.select(nil, [s2])
+ # retry
+ # end
+ #
+ # By specifying `exception: false`, the options hash allows you to
+ # indicate that connect_nonblock should not raise an IO::WaitReadable or
+ # IO::WaitWritable exception, but return the symbol :wait_readable or
+ # :wait_writable instead.
+ def connect_nonblock(exception: true)
+ __connect_nonblock(exception)
+ end
+
private
def using_anon_cipher?
diff --git a/ext/openssl/ossl_ssl.c b/ext/openssl/ossl_ssl.c
index 553eb14..5018dcb 100644
--- a/ext/openssl/ossl_ssl.c
+++ b/ext/openssl/ossl_ssl.c
@@ -1271,14 +1271,19 @@ no_exception_p(VALUE opts)
return 0;
}
+/*
+ * nbex -
+ * * undef - blocking
+ * * true - non-blocking, raise exceptions on common errors
+ * * false - non-blocking, no exceptions on common errors
+ */
static VALUE
-ossl_start_ssl(VALUE self, int (*func)(), const char *funcname, VALUE opts)
+ossl_start_ssl(VALUE self, int (*func)(), const char *funcname, VALUE nbex)
{
SSL *ssl;
rb_io_t *fptr;
int ret, ret2;
VALUE cb_state;
- int nonblock = opts != Qfalse;
rb_ivar_set(self, ID_callback_state, Qnil);
@@ -1297,15 +1302,23 @@ ossl_start_ssl(VALUE self, int (*func)(), const char *funcname, VALUE opts)
switch((ret2 = ssl_get_error(ssl, ret))){
case SSL_ERROR_WANT_WRITE:
- if (no_exception_p(opts)) { return sym_wait_writable; }
- write_would_block(nonblock);
- rb_io_wait_writable(FPTR_TO_FD(fptr));
- continue;
+ switch (nbex) {
+ case Qfalse: return sym_wait_writable;
+ case Qundef:
+ rb_io_wait_writable(FPTR_TO_FD(fptr));
+ continue;
+ default:
+ write_would_block(1);
+ }
case SSL_ERROR_WANT_READ:
- if (no_exception_p(opts)) { return sym_wait_readable; }
- read_would_block(nonblock);
- rb_io_wait_readable(FPTR_TO_FD(fptr));
- continue;
+ switch (nbex) {
+ case Qfalse: return sym_wait_readable;
+ case Qundef:
+ rb_io_wait_readable(FPTR_TO_FD(fptr));
+ continue;
+ default:
+ read_would_block(1);
+ }
case SSL_ERROR_SYSCALL:
if (errno) rb_sys_fail(funcname);
ossl_raise(eSSLError, "%s SYSCALL returned=%d errno=%d state=%s", funcname, ret2, errno, SSL_state_string_long(ssl));
@@ -1329,40 +1342,15 @@ ossl_ssl_connect(VALUE self)
{
ossl_ssl_setup(self);
- return ossl_start_ssl(self, SSL_connect, "SSL_connect", Qfalse);
+ return ossl_start_ssl(self, SSL_connect, "SSL_connect", Qundef);
}
-/*
- * call-seq:
- * ssl.connect_nonblock([options]) => self
- *
- * Initiates the SSL/TLS handshake as a client in non-blocking manner.
- *
- * # emulates blocking connect
- * begin
- * ssl.connect_nonblock
- * rescue IO::WaitReadable
- * IO.select([s2])
- * retry
- * rescue IO::WaitWritable
- * IO.select(nil, [s2])
- * retry
- * end
- *
- * By specifying `exception: false`, the options hash allows you to indicate
- * that connect_nonblock should not raise an IO::WaitReadable or
- * IO::WaitWritable exception, but return the symbol :wait_readable or
- * :wait_writable instead.
- */
static VALUE
-ossl_ssl_connect_nonblock(int argc, VALUE *argv, VALUE self)
+ossl_ssl_connect_nonblock(VALUE self, VALUE ex)
{
- VALUE opts;
- rb_scan_args(argc, argv, "0:", &opts);
-
ossl_ssl_setup(self);
- return ossl_start_ssl(self, SSL_connect, "SSL_connect", opts);
+ return ossl_start_ssl(self, SSL_connect, "SSL_connect", ex);
}
/*
@@ -1377,40 +1365,15 @@ ossl_ssl_accept(VALUE self)
{
ossl_ssl_setup(self);
- return ossl_start_ssl(self, SSL_accept, "SSL_accept", Qfalse);
+ return ossl_start_ssl(self, SSL_accept, "SSL_accept", Qundef);
}
-/*
- * call-seq:
- * ssl.accept_nonblock([options]) => self
- *
- * Initiates the SSL/TLS handshake as a server in non-blocking manner.
- *
- * # emulates blocking accept
- * begin
- * ssl.accept_nonblock
- * rescue IO::WaitReadable
- * IO.select([s2])
- * retry
- * rescue IO::WaitWritable
- * IO.select(nil, [s2])
- * retry
- * end
- *
- * By specifying `exception: false`, the options hash allows you to indicate
- * that accept_nonblock should not raise an IO::WaitReadable or
- * IO::WaitWritable exception, but return the symbol :wait_readable or
- * :wait_writable instead.
- */
static VALUE
-ossl_ssl_accept_nonblock(int argc, VALUE *argv, VALUE self)
+ossl_ssl_accept_nonblock(VALUE self, VALUE ex)
{
- VALUE opts;
-
- rb_scan_args(argc, argv, "0:", &opts);
ossl_ssl_setup(self);
- return ossl_start_ssl(self, SSL_accept, "SSL_accept", opts);
+ return ossl_start_ssl(self, SSL_accept, "SSL_accept", ex);
}
static VALUE
@@ -2287,9 +2250,11 @@ Init_ossl_ssl(void)
rb_define_const(mSSLExtConfig, "OPENSSL_NO_SOCK", Qfalse);
rb_define_alloc_func(cSSLSocket, ossl_ssl_s_alloc);
rb_define_method(cSSLSocket, "connect", ossl_ssl_connect, 0);
- rb_define_method(cSSLSocket, "connect_nonblock", ossl_ssl_connect_nonblock, -1);
+ rb_define_private_method(cSSLSocket, "__connect_nonblock",
+ ossl_ssl_connect_nonblock, 1);
rb_define_method(cSSLSocket, "accept", ossl_ssl_accept, 0);
- rb_define_method(cSSLSocket, "accept_nonblock", ossl_ssl_accept_nonblock, -1);
+ rb_define_private_method(cSSLSocket, "__accept_nonblock",
+ ossl_ssl_accept_nonblock, 1);
rb_define_method(cSSLSocket, "sysread", ossl_ssl_read, -1);
rb_define_private_method(cSSLSocket, "sysread_nonblock", ossl_ssl_read_nonblock, -1);
rb_define_method(cSSLSocket, "syswrite", ossl_ssl_write, 1);
--
EW
^ permalink raw reply related [flat|nested] only message in thread
only message in thread, other threads:[~2015-12-02 0:11 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-12-02 0:11 [PATCH] openssl: avoid kwarg parsing from C API at startup Eric Wong
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).