Feature #11318 ยป 0001-delay-exception-false-checks-for-minor-speedup.patch
benchmark/bm_io_nonblock_noex.rb | ||
---|---|---|
nr = 1_000_000
|
||
i = 0
|
||
msg = '.'
|
||
buf = '.'
|
||
noex = { exception: false }
|
||
begin
|
||
r, w = IO.pipe
|
||
while i < nr
|
||
i += 1
|
||
w.write_nonblock(msg, noex)
|
||
r.read_nonblock(1, buf, noex)
|
||
end
|
||
rescue ArgumentError # old Rubies
|
||
while i < nr
|
||
i += 1
|
||
w.write_nonblock(msg)
|
||
r.read_nonblock(1, buf)
|
||
end
|
||
ensure
|
||
r.close
|
||
w.close
|
||
end
|
ext/openssl/ossl_ssl.c | ||
---|---|---|
}
|
||
}
|
||
static int
|
||
no_exception_p(VALUE opts)
|
||
{
|
||
if (RB_TYPE_P(opts, T_HASH) &&
|
||
rb_hash_lookup2(opts, sym_exception, Qundef) == Qfalse)
|
||
return 1;
|
||
return 0;
|
||
}
|
||
static VALUE
|
||
ossl_start_ssl(VALUE self, int (*func)(), const char *funcname,
|
||
int nonblock, int no_exception)
|
||
ossl_start_ssl(VALUE self, int (*func)(), const char *funcname, VALUE opts)
|
||
{
|
||
SSL *ssl;
|
||
rb_io_t *fptr;
|
||
int ret, ret2;
|
||
VALUE cb_state;
|
||
int nonblock = opts != Qfalse;
|
||
rb_ivar_set(self, ID_callback_state, Qnil);
|
||
... | ... | |
switch((ret2 = ssl_get_error(ssl, ret))){
|
||
case SSL_ERROR_WANT_WRITE:
|
||
if (no_exception) { return sym_wait_writable; }
|
||
if (no_exception_p(opts)) { return sym_wait_writable; }
|
||
write_would_block(nonblock);
|
||
rb_io_wait_writable(FPTR_TO_FD(fptr));
|
||
continue;
|
||
case SSL_ERROR_WANT_READ:
|
||
if (no_exception) { return sym_wait_readable; }
|
||
if (no_exception_p(opts)) { return sym_wait_readable; }
|
||
read_would_block(nonblock);
|
||
rb_io_wait_readable(FPTR_TO_FD(fptr));
|
||
continue;
|
||
... | ... | |
ossl_ssl_connect(VALUE self)
|
||
{
|
||
ossl_ssl_setup(self);
|
||
return ossl_start_ssl(self, SSL_connect, "SSL_connect", 0, 0);
|
||
}
|
||
static int
|
||
get_no_exception(VALUE opts)
|
||
{
|
||
if (!NIL_P(opts) && Qfalse == rb_hash_lookup2(opts, sym_exception, Qundef))
|
||
return 1;
|
||
return 0;
|
||
return ossl_start_ssl(self, SSL_connect, "SSL_connect", Qfalse);
|
||
}
|
||
/*
|
||
... | ... | |
static VALUE
|
||
ossl_ssl_connect_nonblock(int argc, VALUE *argv, VALUE self)
|
||
{
|
||
int no_exception;
|
||
VALUE opts = Qnil;
|
||
VALUE opts;
|
||
rb_scan_args(argc, argv, "0:", &opts);
|
||
no_exception = get_no_exception(opts);
|
||
ossl_ssl_setup(self);
|
||
return ossl_start_ssl(self, SSL_connect, "SSL_connect", 1, no_exception);
|
||
return ossl_start_ssl(self, SSL_connect, "SSL_connect", opts);
|
||
}
|
||
/*
|
||
... | ... | |
ossl_ssl_accept(VALUE self)
|
||
{
|
||
ossl_ssl_setup(self);
|
||
return ossl_start_ssl(self, SSL_accept, "SSL_accept", 0, 0);
|
||
return ossl_start_ssl(self, SSL_accept, "SSL_accept", Qfalse);
|
||
}
|
||
/*
|
||
... | ... | |
static VALUE
|
||
ossl_ssl_accept_nonblock(int argc, VALUE *argv, VALUE self)
|
||
{
|
||
int no_exception;
|
||
VALUE opts = Qnil;
|
||
VALUE opts;
|
||
rb_scan_args(argc, argv, "0:", &opts);
|
||
no_exception = get_no_exception(opts);
|
||
ossl_ssl_setup(self);
|
||
return ossl_start_ssl(self, SSL_accept, "SSL_accept", 1, no_exception);
|
||
return ossl_start_ssl(self, SSL_accept, "SSL_accept", opts);
|
||
}
|
||
static VALUE
|
||
... | ... | |
{
|
||
SSL *ssl;
|
||
int ilen, nread = 0;
|
||
int no_exception = 0;
|
||
VALUE len, str;
|
||
rb_io_t *fptr;
|
||
VALUE opts = Qnil;
|
||
if (nonblock) {
|
||
rb_scan_args(argc, argv, "11:", &len, &str, &opts);
|
||
no_exception = get_no_exception(opts);
|
||
} else {
|
||
rb_scan_args(argc, argv, "11", &len, &str);
|
||
}
|
||
... | ... | |
case SSL_ERROR_NONE:
|
||
goto end;
|
||
case SSL_ERROR_ZERO_RETURN:
|
||
if (no_exception) { return Qnil; }
|
||
if (no_exception_p(opts)) { return Qnil; }
|
||
rb_eof_error();
|
||
case SSL_ERROR_WANT_WRITE:
|
||
if (no_exception) { return sym_wait_writable; }
|
||
if (no_exception_p(opts)) { return sym_wait_writable; }
|
||
write_would_block(nonblock);
|
||
rb_io_wait_writable(FPTR_TO_FD(fptr));
|
||
continue;
|
||
case SSL_ERROR_WANT_READ:
|
||
if (no_exception) { return sym_wait_readable; }
|
||
if (no_exception_p(opts)) { return sym_wait_readable; }
|
||
read_would_block(nonblock);
|
||
rb_io_wait_readable(FPTR_TO_FD(fptr));
|
||
continue;
|
||
case SSL_ERROR_SYSCALL:
|
||
if(ERR_peek_error() == 0 && nread == 0) {
|
||
if (no_exception) { return Qnil; }
|
||
if (no_exception_p(opts)) { return Qnil; }
|
||
rb_eof_error();
|
||
}
|
||
rb_sys_fail(0);
|
||
... | ... | |
}
|
||
static VALUE
|
||
ossl_ssl_write_internal(VALUE self, VALUE str, int nonblock, int no_exception)
|
||
ossl_ssl_write_internal(VALUE self, VALUE str, VALUE opts)
|
||
{
|
||
SSL *ssl;
|
||
int nwrite = 0;
|
||
rb_io_t *fptr;
|
||
int nonblock = opts != Qfalse;
|
||
StringValue(str);
|
||
GetSSL(self, ssl);
|
||
... | ... | |
case SSL_ERROR_NONE:
|
||
goto end;
|
||
case SSL_ERROR_WANT_WRITE:
|
||
if (no_exception) { return sym_wait_writable; }
|
||
if (no_exception_p(opts)) { return sym_wait_writable; }
|
||
write_would_block(nonblock);
|
||
rb_io_wait_writable(FPTR_TO_FD(fptr));
|
||
continue;
|
||
case SSL_ERROR_WANT_READ:
|
||
if (no_exception) { return sym_wait_readable; }
|
||
if (no_exception_p(opts)) { return sym_wait_readable; }
|
||
read_would_block(nonblock);
|
||
rb_io_wait_readable(FPTR_TO_FD(fptr));
|
||
continue;
|
||
... | ... | |
static VALUE
|
||
ossl_ssl_write(VALUE self, VALUE str)
|
||
{
|
||
return ossl_ssl_write_internal(self, str, 0, 0);
|
||
return ossl_ssl_write_internal(self, str, Qfalse);
|
||
}
|
||
/*
|
||
... | ... | |
static VALUE
|
||
ossl_ssl_write_nonblock(int argc, VALUE *argv, VALUE self)
|
||
{
|
||
VALUE str;
|
||
VALUE opts = Qnil;
|
||
int no_exception;
|
||
VALUE str, opts;
|
||
rb_scan_args(argc, argv, "1:", &str, &opts);
|
||
no_exception = get_no_exception(opts);
|
||
return ossl_ssl_write_internal(self, str, 1, no_exception);
|
||
return ossl_ssl_write_internal(self, str, opts);
|
||
}
|
||
/*
|
ext/stringio/stringio.c | ||
---|---|---|
strio_read_nonblock(int argc, VALUE *argv, VALUE self)
|
||
{
|
||
VALUE opts = Qnil, val;
|
||
int no_exception = 0;
|
||
rb_scan_args(argc, argv, "11:", NULL, NULL, &opts);
|
||
if (!NIL_P(opts)) {
|
||
argc--;
|
||
if (Qfalse == rb_hash_aref(opts, sym_exception))
|
||
no_exception = 1;
|
||
}
|
||
val = strio_read(argc, argv, self);
|
||
if (NIL_P(val)) {
|
||
if (no_exception)
|
||
if (!NIL_P(opts) &&
|
||
rb_hash_lookup2(opts, sym_exception, Qundef) == Qfalse)
|
||
return Qnil;
|
||
else
|
||
rb_eof_error();
|
io.c | ||
---|---|---|
return Qundef;
|
||
}
|
||
static int
|
||
no_exception_p(VALUE opts)
|
||
{
|
||
VALUE except;
|
||
ID id = id_exception;
|
||
rb_get_kwargs(opts, &id, 0, 1, &except);
|
||
return except == Qfalse;
|
||
}
|
||
static VALUE
|
||
io_getpartial(int argc, VALUE *argv, VALUE io, int nonblock, int no_exception)
|
||
io_getpartial(int argc, VALUE *argv, VALUE io, VALUE opts, int nonblock)
|
||
{
|
||
rb_io_t *fptr;
|
||
VALUE length, str;
|
||
... | ... | |
if (!nonblock && rb_io_wait_readable(fptr->fd))
|
||
goto again;
|
||
if (nonblock && (errno == EWOULDBLOCK || errno == EAGAIN)) {
|
||
if (no_exception)
|
||
if (no_exception_p(opts))
|
||
return sym_wait_readable;
|
||
else
|
||
rb_readwrite_sys_fail(RB_IO_WAIT_READABLE, "read would block");
|
||
... | ... | |
{
|
||
VALUE ret;
|
||
ret = io_getpartial(argc, argv, io, 0, 0);
|
||
ret = io_getpartial(argc, argv, io, Qnil, 0);
|
||
if (NIL_P(ret))
|
||
rb_eof_error();
|
||
return ret;
|
||
}
|
||
static VALUE
|
||
get_kwargs_exception(VALUE opts)
|
||
{
|
||
static ID ids[1];
|
||
VALUE except;
|
||
if (!ids[0])
|
||
ids[0] = id_exception;
|
||
rb_get_kwargs(opts, ids, 0, 1, &except);
|
||
return except;
|
||
}
|
||
/*
|
||
* call-seq:
|
||
* ios.read_nonblock(maxlen) -> string
|
||
... | ... | |
static VALUE
|
||
io_read_nonblock(int argc, VALUE *argv, VALUE io)
|
||
{
|
||
VALUE ret;
|
||
VALUE opts = Qnil;
|
||
int no_exception = 0;
|
||
VALUE ret, opts;
|
||
rb_scan_args(argc, argv, "11:", NULL, NULL, &opts);
|
||
if (!NIL_P(opts) && Qfalse == get_kwargs_exception(opts))
|
||
no_exception = 1;
|
||
ret = io_getpartial(argc, argv, io, 1, no_exception);
|
||
ret = io_getpartial(argc, argv, io, opts, 1);
|
||
if (NIL_P(ret)) {
|
||
if (no_exception)
|
||
if (no_exception_p(opts))
|
||
return Qnil;
|
||
else
|
||
rb_eof_error();
|
||
... | ... | |
}
|
||
static VALUE
|
||
io_write_nonblock(VALUE io, VALUE str, int no_exception)
|
||
io_write_nonblock(VALUE io, VALUE str, VALUE opts)
|
||
{
|
||
rb_io_t *fptr;
|
||
long n;
|
||
... | ... | |
if (n == -1) {
|
||
if (errno == EWOULDBLOCK || errno == EAGAIN) {
|
||
if (no_exception) {
|
||
if (no_exception_p(opts)) {
|
||
return sym_wait_writable;
|
||
}
|
||
else {
|
||
... | ... | |
static VALUE
|
||
rb_io_write_nonblock(int argc, VALUE *argv, VALUE io)
|
||
{
|
||
VALUE str;
|
||
VALUE opts = Qnil;
|
||
int no_exceptions = 0;
|
||
VALUE str, opts;
|
||
rb_scan_args(argc, argv, "10:", &str, &opts);
|
||
if (!NIL_P(opts) && Qfalse == get_kwargs_exception(opts))
|
||
no_exceptions = 1;
|
||
return io_write_nonblock(io, str, no_exceptions);
|
||
return io_write_nonblock(io, str, opts);
|
||
}
|
||
/*
|
||
... | ... | |
RUBY_METHOD_FUNC(0), Qnil, rb_eEOFError, (VALUE)0);
|
||
}
|
||
else {
|
||
tmp = io_getpartial(argc, argv, ARGF.current_file, nonblock, 0);
|
||
tmp = io_getpartial(argc, argv, ARGF.current_file, Qnil, nonblock);
|
||
}
|
||
if (NIL_P(tmp)) {
|
||
if (ARGF.next_p == -1) {
|
||
-
|