eagain_readwrite.diff

Charles Nutter, 04/03/2013 10:55 AM

Download (10.5 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;
136 139

  
140
static VALUE rb_eEAGAINWaitReadable;
141
static VALUE rb_eEAGAINWaitWritable;
142
static VALUE rb_eEWOULDBLOCKWaitReadable;
143
static VALUE rb_eEWOULDBLOCKWaitWritable;
144
static VALUE rb_eEINPROGRESSWaitWritable;
145
static VALUE rb_eEINPROGRESSWaitReadable;
146

  
137 147
VALUE rb_stdin, rb_stdout, rb_stderr;
138 148
VALUE rb_deferr;		/* rescue VIM plugin */
139 149
static VALUE orig_stdout, orig_stderr;
......
2342 2352
    }
2343 2353
}
2344 2354

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

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

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

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

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

  
11440 11495
/*
11441 11496
 * Document-class: IOError
11442 11497
 *
......
11645 11700

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

  
11649 11723
#if 0
11650 11724
    /* This is necessary only for forcing rdoc handle File::open */
ext/openssl/ossl_ssl.c (working copy)
29 29
VALUE cSSLContext;
30 30
VALUE cSSLSocket;
31 31

  
32
static VALUE eSSLErrorWaitReadable;
33
static VALUE eSSLErrorWaitWritable;
34

  
32 35
#define ossl_sslctx_set_cert(o,v)        	rb_iv_set((o),"@cert",(v))
33 36
#define ossl_sslctx_set_key(o,v)         	rb_iv_set((o),"@key",(v))
34 37
#define ossl_sslctx_set_client_ca(o,v)   	rb_iv_set((o),"@client_ca",(v))
......
1230 1233
write_would_block(int nonblock)
1231 1234
{
1232 1235
    if (nonblock) {
1233
        VALUE exc = ossl_exc_new(eSSLError, "write would block");
1234
        rb_extend_object(exc, rb_mWaitWritable);
1236
        VALUE exc = ossl_exc_new(eSSLErrorWaitReadable, "write would block");
1235 1237
        rb_exc_raise(exc);
1236 1238
    }
1237 1239
}
......
1240 1242
read_would_block(int nonblock)
1241 1243
{
1242 1244
    if (nonblock) {
1243
        VALUE exc = ossl_exc_new(eSSLError, "read would block");
1244
        rb_extend_object(exc, rb_mWaitReadable);
1245
        VALUE exc = ossl_exc_new(eSSLErrorWaitReadable, "read would block");
1245 1246
        rb_exc_raise(exc);
1246 1247
    }
1247 1248
}
......
1846 1847
     * Generic error class raised by SSLSocket and SSLContext.
1847 1848
     */
1848 1849
    eSSLError = rb_define_class_under(mSSL, "SSLError", eOSSLError);
1850
    eSSLErrorWaitReadable = rb_define_class_under(mSSL, "SSLErrorWaitReadable", eSSLError);
1851
    rb_include_module(eSSLErrorWaitReadable, rb_mWaitReadable);
1852
    eSSLErrorWaitWritable = rb_define_class_under(mSSL, "SSLErrorWaitWritable", eSSLError);
1853
    rb_include_module(eSSLErrorWaitWritable, rb_mWaitWritable);
1849 1854

  
1850 1855
    Init_ossl_ssl_session();
1851 1856

  
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