Project

General

Profile

Feature #10532 ยป 0001-accept_nonblock-supports-exception-false.patch

normalperson (Eric Wong), 11/20/2014 07:48 PM

View differences:

ext/socket/init.c
29 29
#endif
30 30

  
31 31
int rsock_do_not_reverse_lookup = 1;
32
static VALUE sym_exception, sym_wait_readable;
32 33

  
33 34
void
34 35
rsock_raise_socket_error(const char *reason, int error)
......
505 506
    return ret;
506 507
}
507 508

  
508

  
509 509
VALUE
510
rsock_s_accept_nonblock(VALUE klass, rb_io_t *fptr, struct sockaddr *sockaddr, socklen_t *len)
510
rsock_s_accept_nonblock(int argc, VALUE *argv, VALUE klass, rb_io_t *fptr,
511
			struct sockaddr *sockaddr, socklen_t *len)
511 512
{
512 513
    int fd2;
514
    int ex = 1;
515
    VALUE opts = Qnil;
516

  
517
    rb_scan_args(argc, argv, "0:", &opts);
518

  
519
    if (!NIL_P(opts) && Qfalse == rb_hash_aref(opts, sym_exception))
520
	ex = 0;
513 521

  
514 522
    rb_secure(3);
515 523
    rb_io_set_nonblock(fptr);
......
524 532
#if defined EPROTO
525 533
	  case EPROTO:
526 534
#endif
535
            if (!ex)
536
		return sym_wait_readable;
527 537
            rb_readwrite_sys_fail(RB_IO_WAIT_READABLE, "accept(2) would block");
528 538
	}
529 539
        rb_sys_fail("accept(2)");
......
612 622
    rsock_init_addrinfo();
613 623
    rsock_init_sockifaddr();
614 624
    rsock_init_socket_constants();
625

  
626
#undef rb_intern
627
    sym_exception = ID2SYM(rb_intern("exception"));
628
    sym_wait_readable = ID2SYM(rb_intern("wait_readable"));
615 629
}
ext/socket/rubysocket.h
343 343
int rsock_connect(int fd, const struct sockaddr *sockaddr, int len, int socks);
344 344

  
345 345
VALUE rsock_s_accept(VALUE klass, int fd, struct sockaddr *sockaddr, socklen_t *len);
346
VALUE rsock_s_accept_nonblock(VALUE klass, rb_io_t *fptr, struct sockaddr *sockaddr, socklen_t *len);
346
VALUE rsock_s_accept_nonblock(int argc, VALUE *argv, VALUE klass, rb_io_t *fptr, struct sockaddr *sockaddr, socklen_t *len);
347 347
VALUE rsock_sock_listen(VALUE sock, VALUE log);
348 348

  
349 349
VALUE rsock_sockopt_new(int family, int level, int optname, VALUE data);
ext/socket/socket.c
944 944
 * * Socket#accept
945 945
 */
946 946
static VALUE
947
sock_accept_nonblock(VALUE sock)
947
sock_accept_nonblock(int argc, VALUE *argv, VALUE sock)
948 948
{
949 949
    rb_io_t *fptr;
950 950
    VALUE sock2;
951 951
    union_sockaddr buf;
952
    struct sockaddr *addr = &buf.addr;
952 953
    socklen_t len = (socklen_t)sizeof buf;
953 954

  
954 955
    GetOpenFile(sock, fptr);
955
    sock2 = rsock_s_accept_nonblock(rb_cSocket, fptr, &buf.addr, &len);
956
    sock2 = rsock_s_accept_nonblock(argc, argv, rb_cSocket, fptr, addr, &len);
957

  
958
    if (SYMBOL_P(sock2)) /* :wait_readable */
959
	return sock2;
956 960
    return rb_assoc_new(sock2, rsock_io_socket_addrinfo(sock2, &buf.addr, len));
957 961
}
958 962

  
......
2154 2158
    rb_define_method(rb_cSocket, "bind", sock_bind, 1);
2155 2159
    rb_define_method(rb_cSocket, "listen", rsock_sock_listen, 1);
2156 2160
    rb_define_method(rb_cSocket, "accept", sock_accept, 0);
2157
    rb_define_method(rb_cSocket, "accept_nonblock", sock_accept_nonblock, 0);
2161
    rb_define_method(rb_cSocket, "accept_nonblock", sock_accept_nonblock, -1);
2158 2162
    rb_define_method(rb_cSocket, "sysaccept", sock_sysaccept, 0);
2159 2163

  
2160 2164
    rb_define_method(rb_cSocket, "recvfrom", sock_recvfrom, -1);
ext/socket/tcpserver.c
98 98
 * * Socket#accept
99 99
 */
100 100
static VALUE
101
tcp_accept_nonblock(VALUE sock)
101
tcp_accept_nonblock(int argc, VALUE *argv, VALUE sock)
102 102
{
103 103
    rb_io_t *fptr;
104 104
    union_sockaddr from;
......
106 106

  
107 107
    GetOpenFile(sock, fptr);
108 108
    fromlen = (socklen_t)sizeof(from);
109
    return rsock_s_accept_nonblock(rb_cTCPSocket, fptr, &from.addr, &fromlen);
109
    return rsock_s_accept_nonblock(argc, argv, rb_cTCPSocket, fptr, &from.addr, &fromlen);
110 110
}
111 111

  
112 112
/*
......
171 171
     */
172 172
    rb_cTCPServer = rb_define_class("TCPServer", rb_cTCPSocket);
173 173
    rb_define_method(rb_cTCPServer, "accept", tcp_accept, 0);
174
    rb_define_method(rb_cTCPServer, "accept_nonblock", tcp_accept_nonblock, 0);
174
    rb_define_method(rb_cTCPServer, "accept_nonblock", tcp_accept_nonblock, -1);
175 175
    rb_define_method(rb_cTCPServer, "sysaccept", tcp_sysaccept, 0);
176 176
    rb_define_method(rb_cTCPServer, "initialize", tcp_svr_init, -1);
177 177
    rb_define_method(rb_cTCPServer, "listen", rsock_sock_listen, 1); /* in socket.c */
ext/socket/unixserver.c
91 91
 * * Socket#accept
92 92
 */
93 93
static VALUE
94
unix_accept_nonblock(VALUE sock)
94
unix_accept_nonblock(int argc, VALUE *argv, VALUE sock)
95 95
{
96 96
    rb_io_t *fptr;
97 97
    struct sockaddr_un from;
......
99 99

  
100 100
    GetOpenFile(sock, fptr);
101 101
    fromlen = (socklen_t)sizeof(from);
102
    return rsock_s_accept_nonblock(rb_cUNIXSocket, fptr,
102
    return rsock_s_accept_nonblock(argc, argv, rb_cUNIXSocket, fptr,
103 103
			           (struct sockaddr *)&from, &fromlen);
104 104
}
105 105

  
......
148 148
    rb_cUNIXServer = rb_define_class("UNIXServer", rb_cUNIXSocket);
149 149
    rb_define_method(rb_cUNIXServer, "initialize", unix_svr_init, 1);
150 150
    rb_define_method(rb_cUNIXServer, "accept", unix_accept, 0);
151
    rb_define_method(rb_cUNIXServer, "accept_nonblock", unix_accept_nonblock, 0);
151
    rb_define_method(rb_cUNIXServer, "accept_nonblock", unix_accept_nonblock, -1);
152 152
    rb_define_method(rb_cUNIXServer, "sysaccept", unix_sysaccept, 0);
153 153
    rb_define_method(rb_cUNIXServer, "listen", rsock_sock_listen, 1); /* in socket.c */
154 154
#endif
test/socket/test_nonblock.rb
13 13
    serv.bind(Socket.sockaddr_in(0, "127.0.0.1"))
14 14
    serv.listen(5)
15 15
    assert_raise(IO::WaitReadable) { serv.accept_nonblock }
16
    assert_equal :wait_readable, serv.accept_nonblock(exception: false)
17
    assert_raise(IO::WaitReadable) { serv.accept_nonblock(exception: true) }
16 18
    c = Socket.new(Socket::AF_INET, Socket::SOCK_STREAM, 0)
17 19
    c.connect(serv.getsockname)
18 20
    begin
test/socket/test_tcp.rb
76 76
      th.join
77 77
    }
78 78
  end
79

  
80
  def test_accept_nonblock
81
    svr = TCPServer.new("localhost", 0)
82
    assert_raises(IO::WaitReadable) { svr.accept_nonblock }
83
    assert_equal :wait_readable, svr.accept_nonblock(exception: false)
84
    assert_raises(IO::WaitReadable) { svr.accept_nonblock(exception: true) }
85
  end
79 86
end if defined?(TCPSocket)
test/socket/test_unix.rb
663 663
    assert(s0.closed?)
664 664
  end
665 665

  
666
  def test_accept_nonblock
667
    bound_unix_socket(UNIXServer) {|serv, path|
668
      assert_raises(IO::WaitReadable) { serv.accept_nonblock }
669
      assert_raises(IO::WaitReadable) { serv.accept_nonblock(exception: true) }
670
      assert_equal :wait_readable, serv.accept_nonblock(exception: false)
671
    }
672
  end
666 673
end if defined?(UNIXSocket) && /cygwin/ !~ RUBY_PLATFORM
667
-