Feature #6154 » eagain_readwrite.diff
error.c | ||
---|---|---|
#define WEXITSTATUS(status) (status)
|
||
#endif
|
||
VALUE rb_eEAGAIN;
|
||
VALUE rb_eEWOULDBLOCK;
|
||
extern const char ruby_description[];
|
||
#define REPORTBUG_MSG \
|
||
... | ... | |
if (!st_lookup(syserr_tbl, n, &error)) {
|
||
error = rb_define_class_under(rb_mErrno, name, rb_eSystemCallError);
|
||
|
||
if (n == EAGAIN) {
|
||
rb_eEAGAIN = error;
|
||
if (n == EWOULDBLOCK) rb_eEWOULDBLOCK = error; /* same value */
|
||
}
|
||
else if (n == EWOULDBLOCK) { /* different error */
|
||
rb_eEWOULDBLOCK = error;
|
||
}
|
||
|
||
rb_define_const(error, "Errno", INT2NUM(n));
|
||
st_add_direct(syserr_tbl, n, error);
|
||
}
|
ext/socket/ancdata.c | ||
---|---|---|
if (ss == -1) {
|
||
if (nonblock && (errno == EWOULDBLOCK || errno == EAGAIN))
|
||
rb_mod_sys_fail(rb_mWaitWritable, "sendmsg(2) would block");
|
||
rb_readwrite_sys_fail(1, "sendmsg(2) would block");
|
||
rb_sys_fail("sendmsg(2)");
|
||
}
|
||
... | ... | |
if (ss == -1) {
|
||
if (nonblock && (errno == EWOULDBLOCK || errno == EAGAIN))
|
||
rb_mod_sys_fail(rb_mWaitReadable, "recvmsg(2) would block");
|
||
rb_readwrite_sys_fail(0, "recvmsg(2) would block");
|
||
#if defined(HAVE_ST_MSG_CONTROL)
|
||
if (!gc_done && (errno == EMFILE || errno == EMSGSIZE)) {
|
||
/*
|
ext/socket/init.c | ||
---|---|---|
#if defined(EWOULDBLOCK) && EWOULDBLOCK != EAGAIN
|
||
case EWOULDBLOCK:
|
||
#endif
|
||
rb_mod_sys_fail(rb_mWaitReadable, "recvfrom(2) would block");
|
||
rb_readwrite_sys_fail(0, "recvfrom(2) would block");
|
||
}
|
||
rb_sys_fail("recvfrom(2)");
|
||
}
|
||
... | ... | |
#if defined EPROTO
|
||
case EPROTO:
|
||
#endif
|
||
rb_mod_sys_fail(rb_mWaitReadable, "accept(2) would block");
|
||
rb_readwrite_sys_fail(0, "accept(2) would block");
|
||
}
|
||
rb_sys_fail("accept(2)");
|
||
}
|
include/ruby/ruby.h | ||
---|---|---|
NORETURN(void rb_sys_fail_str(VALUE));
|
||
NORETURN(void rb_mod_sys_fail(VALUE, const char*));
|
||
NORETURN(void rb_mod_sys_fail_str(VALUE, VALUE));
|
||
NORETURN(void rb_readwrite_sys_fail(int, const char*));
|
||
NORETURN(void rb_iter_break(void));
|
||
NORETURN(void rb_iter_break_value(VALUE));
|
||
NORETURN(void rb_exit(int));
|
io.c | ||
---|---|---|
VALUE rb_eIOError;
|
||
VALUE rb_mWaitReadable;
|
||
VALUE rb_mWaitWritable;
|
||
extern VALUE rb_eEAGAIN;
|
||
extern VALUE rb_eEWOULDBLOCK;
|
||
VALUE rb_eEAGAINReadable;
|
||
VALUE rb_eEAGAINWritable;
|
||
VALUE rb_eEWOULDBLOCKReadable;
|
||
VALUE rb_eEWOULDBLOCKWritable;
|
||
VALUE rb_stdin, rb_stdout, rb_stderr;
|
||
VALUE rb_deferr; /* rescue VIM plugin */
|
||
... | ... | |
if (!nonblock && rb_io_wait_readable(fptr->fd))
|
||
goto again;
|
||
if (nonblock && (errno == EWOULDBLOCK || errno == EAGAIN))
|
||
rb_mod_sys_fail(rb_mWaitReadable, "read would block");
|
||
rb_readwrite_sys_fail(0, "read would block");
|
||
rb_sys_fail_path(fptr->pathv);
|
||
}
|
||
}
|
||
... | ... | |
if (n == -1) {
|
||
if (errno == EWOULDBLOCK || errno == EAGAIN)
|
||
rb_mod_sys_fail(rb_mWaitWritable, "write would block");
|
||
rb_readwrite_sys_fail(1, "write would block");
|
||
rb_sys_fail_path(fptr->pathv);
|
||
}
|
||
... | ... | |
return rb_io_write(argf_write_io(argf), str);
|
||
}
|
||
void
|
||
rb_readwrite_sys_fail(int writable, const char *mesg)
|
||
{
|
||
VALUE arg;
|
||
int n = errno;
|
||
arg = mesg ? rb_str_new2(mesg) : Qnil;
|
||
if (writable) {
|
||
if (n == EAGAIN) {
|
||
rb_exc_raise(rb_class_new_instance(1, &arg, rb_eEAGAINWritable));
|
||
}
|
||
else if (n == EWOULDBLOCK) {
|
||
rb_exc_raise(rb_class_new_instance(1, &arg, rb_eEWOULDBLOCKWritable));
|
||
}
|
||
else {
|
||
rb_mod_sys_fail_str(rb_mWaitWritable, arg);
|
||
}
|
||
}
|
||
else {
|
||
if (n == EAGAIN) {
|
||
rb_exc_raise(rb_class_new_instance(1, &arg, rb_eEAGAINReadable));
|
||
}
|
||
else if (n == EWOULDBLOCK) {
|
||
rb_exc_raise(rb_class_new_instance(1, &arg, rb_eEWOULDBLOCKReadable));
|
||
}
|
||
else {
|
||
rb_mod_sys_fail_str(rb_mWaitReadable, arg);
|
||
}
|
||
}
|
||
}
|
||
/*
|
||
* Document-class: IOError
|
||
*
|
||
... | ... | |
rb_mWaitReadable = rb_define_module_under(rb_cIO, "WaitReadable");
|
||
rb_mWaitWritable = rb_define_module_under(rb_cIO, "WaitWritable");
|
||
rb_eEAGAINReadable = rb_define_class_under(rb_cIO, "EAGAINReadable", rb_eEAGAIN);
|
||
rb_include_module(rb_eEAGAINReadable, rb_mWaitReadable);
|
||
rb_eEAGAINWritable = rb_define_class_under(rb_cIO, "EAGAINWritable", rb_eEAGAIN);
|
||
rb_include_module(rb_eEAGAINWritable, rb_mWaitWritable);
|
||
if (EAGAIN == EWOULDBLOCK) {
|
||
rb_eEWOULDBLOCKReadable = rb_eEAGAINReadable;
|
||
rb_define_const(rb_cIO, "EWOULDBLOCKReadable", rb_eEAGAINReadable);
|
||
rb_eEWOULDBLOCKWritable = rb_eEAGAINWritable;
|
||
rb_define_const(rb_cIO, "EWOULDBLOCKWritable", rb_eEAGAINWritable);
|
||
}
|
||
else {
|
||
rb_eEWOULDBLOCKReadable = rb_define_class_under(rb_cIO, "EWOULDBLOCKReadable", rb_eEWOULDBLOCK);
|
||
rb_include_module(rb_eEWOULDBLOCKReadable, rb_mWaitReadable);
|
||
rb_eEWOULDBLOCKWritable = rb_define_class_under(rb_cIO, "EWOULDBLOCKWritable", rb_eEWOULDBLOCK);
|
||
rb_include_module(rb_eEWOULDBLOCKWritable, rb_mWaitWritable);
|
||
}
|
||
#if 0
|
||
/* This is necessary only for forcing rdoc handle File::open */
|
test/socket/test_unix.rb | ||
---|---|---|
def test_dgram_pair
|
||
s1, s2 = UNIXSocket.pair(Socket::SOCK_DGRAM)
|
||
assert_raise(Errno::EAGAIN) { s1.recv_nonblock(10) }
|
||
begin
|
||
s1.recv_nonblock(10)
|
||
fail
|
||
rescue => e
|
||
assert(Errno::EAGAIN === e)
|
||
assert(IO::WaitReadable === e)
|
||
end
|
||
s2.send("", 0)
|
||
s2.send("haha", 0)
|
||
s2.send("", 0)
|