eagain_readwrite.diff

Charles Nutter, 04/03/2013 07:20 AM

Download (10.3 KB)

View differences:

include/ruby/ruby.h (working copy)
1356 1356
NORETURN(void rb_sys_fail_str(VALUE));
1357 1357
NORETURN(void rb_mod_sys_fail(VALUE, const char*));
1358 1358
NORETURN(void rb_mod_sys_fail_str(VALUE, VALUE));
1359
NORETURN(void rb_readwrite_sys_fail(int, const char*));
1359 1360
NORETURN(void rb_iter_break(void));
1360 1361
NORETURN(void rb_iter_break_value(VALUE));
1361 1362
NORETURN(void rb_exit(int));
io.c (working copy)
133 133
VALUE rb_eIOError;
134 134
VALUE rb_mWaitReadable;
135 135
VALUE rb_mWaitWritable;
136
extern VALUE rb_eEAGAIN;
137
extern VALUE rb_eEWOULDBLOCK;
138
extern VALUE rb_eEINPROGRESS;
139
VALUE rb_eEAGAINWaitReadable;
140
VALUE rb_eEAGAINWaitWritable;
141
VALUE rb_eEWOULDBLOCKWaitReadable;
142
VALUE rb_eEWOULDBLOCKWaitWritable;
143
VALUE rb_eEINPROGRESSWaitWritable;
144
VALUE rb_eEINPROGRESSWaitReadable;
136 145

  
137 146
VALUE rb_stdin, rb_stdout, rb_stderr;
138 147
VALUE rb_deferr;		/* rescue VIM plugin */
......
2342 2351
    }
2343 2352
}
2344 2353

  
2354
void
2355
rb_readwrite_sys_fail(int writable, const char *mesg);
2356

  
2345 2357
static VALUE
2346 2358
io_getpartial(int argc, VALUE *argv, VALUE io, int nonblock)
2347 2359
{
......
2380 2392
            if (!nonblock && rb_io_wait_readable(fptr->fd))
2381 2393
                goto again;
2382 2394
            if (nonblock && (errno == EWOULDBLOCK || errno == EAGAIN))
2383
                rb_mod_sys_fail(rb_mWaitReadable, "read would block");
2395
                rb_readwrite_sys_fail(0, "read would block");
2384 2396
            rb_sys_fail_path(fptr->pathv);
2385 2397
        }
2386 2398
    }
......
2599 2611

  
2600 2612
    if (n == -1) {
2601 2613
        if (errno == EWOULDBLOCK || errno == EAGAIN)
2602
            rb_mod_sys_fail(rb_mWaitWritable, "write would block");
2614
            rb_readwrite_sys_fail(1, "write would block");
2603 2615
        rb_sys_fail_path(fptr->pathv);
2604 2616
    }
2605 2617

  
......
11437 11449
    return rb_io_write(argf_write_io(argf), str);
11438 11450
}
11439 11451

  
11452
void
11453
rb_readwrite_sys_fail(int writable, const char *mesg)
11454
{
11455
    VALUE arg;
11456
    int n = errno;
11457
    arg = mesg ? rb_str_new2(mesg) : Qnil;
11458
    if (writable) {
11459
	switch (n) {
11460
	    case EAGAIN:
11461
		rb_exc_raise(rb_class_new_instance(1, &arg, rb_eEAGAINWaitWritable));
11462
		break;
11463
#if EAGAIN != EWOULDBLOCK
11464
	    case EWOULDBLOCK:
11465
		rb_exc_raise(rb_class_new_instance(1, &arg, rb_eEWOULDBLOCKWaitWritable));
11466
		break;
11467
#endif
11468
	    case EINPROGRESS:
11469
		rb_exc_raise(rb_class_new_instance(1, &arg, rb_eEINPROGRESSWaitWritable));
11470
		break;
11471
	    default:
11472
		rb_mod_sys_fail_str(rb_mWaitWritable, arg);
11473
	}
11474
    }
11475
    else {
11476
	switch (n) {
11477
	    case EAGAIN:
11478
		rb_exc_raise(rb_class_new_instance(1, &arg, rb_eEAGAINWaitReadable));
11479
		break;
11480
#if EAGAIN != EWOULDBLOCK
11481
	    case EWOULDBLOCK:
11482
		rb_exc_raise(rb_class_new_instance(1, &arg, rb_eEWOULDBLOCKWaitReadable));
11483
		break;
11484
#endif
11485
	    case EINPROGRESS:
11486
		rb_exc_raise(rb_class_new_instance(1, &arg, rb_eEINPROGRESSWaitReadable));
11487
		break;
11488
	    default:
11489
		rb_mod_sys_fail_str(rb_mWaitReadable, arg);
11490
	}
11491
    }
11492
}
11493

  
11440 11494
/*
11441 11495
 * Document-class: IOError
11442 11496
 *
......
11645 11699

  
11646 11700
    rb_mWaitReadable = rb_define_module_under(rb_cIO, "WaitReadable");
11647 11701
    rb_mWaitWritable = rb_define_module_under(rb_cIO, "WaitWritable");
11702
    rb_eEAGAINWaitReadable = rb_define_class_under(rb_cIO, "EAGAINWaitReadable", rb_eEAGAIN);
11703
    rb_include_module(rb_eEAGAINWaitReadable, rb_mWaitReadable);
11704
    rb_eEAGAINWaitWritable = rb_define_class_under(rb_cIO, "EAGAINWaitWritable", rb_eEAGAIN);
11705
    rb_include_module(rb_eEAGAINWaitWritable, rb_mWaitWritable);
11706
    if (EAGAIN == EWOULDBLOCK) {
11707
	rb_eEWOULDBLOCKWaitReadable = rb_eEAGAINWaitReadable;
11708
	rb_define_const(rb_cIO, "EWOULDBLOCKWaitReadable", rb_eEAGAINWaitReadable);
11709
	rb_eEWOULDBLOCKWaitWritable = rb_eEAGAINWaitWritable;
11710
	rb_define_const(rb_cIO, "EWOULDBLOCKWaitWritable", rb_eEAGAINWaitWritable);
11711
    } else {
11712
	rb_eEWOULDBLOCKWaitReadable = rb_define_class_under(rb_cIO, "EWOULDBLOCKRWaiteadable", rb_eEWOULDBLOCK);
11713
	rb_include_module(rb_eEWOULDBLOCKWaitReadable, rb_mWaitReadable);
11714
	rb_eEWOULDBLOCKWaitWritable = rb_define_class_under(rb_cIO, "EWOULDBLOCKWaitWritable", rb_eEWOULDBLOCK);
11715
	rb_include_module(rb_eEWOULDBLOCKWaitWritable, rb_mWaitWritable);
11716
    }
11717
    rb_eEINPROGRESSWaitReadable = rb_define_class_under(rb_cIO, "EINPROGRESSWaitReadable", rb_eEINPROGRESS);
11718
    rb_include_module(rb_eEINPROGRESSWaitReadable, rb_mWaitReadable);
11719
    rb_eEINPROGRESSWaitWritable = rb_define_class_under(rb_cIO, "EINPROGRESSWaitWritable", rb_eEINPROGRESS);
11720
    rb_include_module(rb_eEINPROGRESSWaitWritable, rb_mWaitWritable);
11648 11721

  
11649 11722
#if 0
11650 11723
    /* This is necessary only for forcing rdoc handle File::open */
ext/openssl/ossl_ssl.c (working copy)
26 26

  
27 27
VALUE mSSL;
28 28
VALUE eSSLError;
29
VALUE eSSLErrorWaitReadable;
30
VALUE eSSLErrorWaitWritable;
29 31
VALUE cSSLContext;
30 32
VALUE cSSLSocket;
31 33

  
......
1230 1232
write_would_block(int nonblock)
1231 1233
{
1232 1234
    if (nonblock) {
1233
        VALUE exc = ossl_exc_new(eSSLError, "write would block");
1234
        rb_extend_object(exc, rb_mWaitWritable);
1235
        VALUE exc = ossl_exc_new(eSSLErrorWaitReadable, "write would block");
1235 1236
        rb_exc_raise(exc);
1236 1237
    }
1237 1238
}
......
1240 1241
read_would_block(int nonblock)
1241 1242
{
1242 1243
    if (nonblock) {
1243
        VALUE exc = ossl_exc_new(eSSLError, "read would block");
1244
        rb_extend_object(exc, rb_mWaitReadable);
1244
        VALUE exc = ossl_exc_new(eSSLErrorWaitReadable, "read would block");
1245 1245
        rb_exc_raise(exc);
1246 1246
    }
1247 1247
}
......
1846 1846
     * Generic error class raised by SSLSocket and SSLContext.
1847 1847
     */
1848 1848
    eSSLError = rb_define_class_under(mSSL, "SSLError", eOSSLError);
1849
    eSSLErrorWaitReadable = rb_define_class_under(mSSL, "SSLErrorWaitReadable", eSSLError);
1850
    rb_include_module(eSSLErrorWaitReadable, rb_mWaitReadable);
1851
    eSSLErrorWaitWritable = rb_define_class_under(mSSL, "SSLErrorWaitWritable", eSSLError);
1852
    rb_include_module(eSSLErrorWaitWritable, rb_mWaitWritable);
1849 1853

  
1850 1854
    Init_ossl_ssl_session();
1851 1855

  
ext/socket/init.c (working copy)
222 222
#if defined(EWOULDBLOCK) && EWOULDBLOCK != EAGAIN
223 223
	  case EWOULDBLOCK:
224 224
#endif
225
            rb_mod_sys_fail(rb_mWaitReadable, "recvfrom(2) would block");
225
            rb_readwrite_sys_fail(0, "recvfrom(2) would block");
226 226
	}
227 227
	rb_sys_fail("recvfrom(2)");
228 228
    }
......
537 537
#if defined EPROTO
538 538
	  case EPROTO:
539 539
#endif
540
            rb_mod_sys_fail(rb_mWaitReadable, "accept(2) would block");
540
            rb_readwrite_sys_fail(0, "accept(2) would block");
541 541
	}
542 542
        rb_sys_fail("accept(2)");
543 543
    }
ext/socket/socket.c (working copy)
374 374
    n = connect(fptr->fd, (struct sockaddr*)RSTRING_PTR(addr), RSTRING_LENINT(addr));
375 375
    if (n < 0) {
376 376
        if (errno == EINPROGRESS)
377
            rb_mod_sys_fail(rb_mWaitWritable, "connect(2) would block");
377
            rb_readwrite_sys_fail(1, "connect(2) would block");
378 378
	rb_sys_fail("connect(2)");
379 379
    }
380 380

  
ext/socket/ancdata.c (working copy)
1285 1285

  
1286 1286
    if (ss == -1) {
1287 1287
        if (nonblock && (errno == EWOULDBLOCK || errno == EAGAIN))
1288
            rb_mod_sys_fail(rb_mWaitWritable, "sendmsg(2) would block");
1288
            rb_readwrite_sys_fail(1, "sendmsg(2) would block");
1289 1289
	rb_sys_fail("sendmsg(2)");
1290 1290
    }
1291 1291

  
......
1600 1600

  
1601 1601
    if (ss == -1) {
1602 1602
        if (nonblock && (errno == EWOULDBLOCK || errno == EAGAIN))
1603
            rb_mod_sys_fail(rb_mWaitReadable, "recvmsg(2) would block");
1603
            rb_readwrite_sys_fail(0, "recvmsg(2) would block");
1604 1604
#if defined(HAVE_ST_MSG_CONTROL)
1605 1605
        if (!gc_done && (errno == EMFILE || errno == EMSGSIZE)) {
1606 1606
          /*
error.c (working copy)
39 39
#define WEXITSTATUS(status) (status)
40 40
#endif
41 41

  
42
VALUE rb_eEAGAIN;
43
VALUE rb_eEWOULDBLOCK;
44
VALUE rb_eEINPROGRESS;
45

  
42 46
extern const char ruby_description[];
43 47

  
44 48
#define REPORTBUG_MSG \
......
1183 1187

  
1184 1188
    if (!st_lookup(syserr_tbl, n, &error)) {
1185 1189
	error = rb_define_class_under(rb_mErrno, name, rb_eSystemCallError);
1190
	
1191
	/* capture nonblock errnos for WaitReadable/WaitWritable subclasses */
1192
	switch (n) {
1193
	    case EAGAIN:
1194
	        rb_eEAGAIN = error;
1195
		
1196
#if EAGAIN != EWOULDBLOCK
1197
                break;
1198
	    case EWOULDBLOCK:
1199
#endif
1200

  
1201
		rb_eEWOULDBLOCK = error;
1202
		break;
1203
	    case EINPROGRESS:
1204
		rb_eEINPROGRESS = error;
1205
		break;
1206
	}
1207
	
1186 1208
	rb_define_const(error, "Errno", INT2NUM(n));
1187 1209
	st_add_direct(syserr_tbl, n, error);
1188 1210
    }
test/openssl/test_pair.rb (working copy)
141 141
  def test_read_nonblock
142 142
    ssl_pair {|s1, s2|
143 143
      err = nil
144
      assert_raise(OpenSSL::SSL::SSLError) {
144
      assert_raise(OpenSSL::SSL::SSLErrorWaitReadable) {
145 145
        begin
146 146
          s2.read_nonblock(10)
147 147
        ensure
test/socket/test_unix.rb (working copy)
348 348

  
349 349
  def test_dgram_pair
350 350
    s1, s2 = UNIXSocket.pair(Socket::SOCK_DGRAM)
351
    assert_raise(Errno::EAGAIN) { s1.recv_nonblock(10) }
351
    begin
352
      s1.recv_nonblock(10)
353
      fail
354
    rescue => e
355
      assert(IO::EAGAINWaitReadable === e)
356
      assert(IO::WaitReadable === e)
357
    end
352 358
    s2.send("", 0)
353 359
    s2.send("haha", 0)
354 360
    s2.send("", 0)
......
357 363
    assert_equal("haha", s1.recv(10))
358 364
    assert_equal("", s1.recv(10))
359 365
    assert_equal("", s1.recv(10))
360
    assert_raise(Errno::EAGAIN) { s1.recv_nonblock(10) }
366
    assert_raise(IO::EAGAINWaitReadable) { s1.recv_nonblock(10) }
361 367
  ensure
362 368
    s1.close if s1
363 369
    s2.close if s2