From: Nobuyoshi Nakada Date: 2009-01-19T05:01:28+09:00 Subject: [ruby-dev:37783] [Feature:1.9] backlog option for TCPServer and UNIXServer なかだです。 以前からときおり要望のあったので、{TCP,UNIX}Server.newで listen()するbacklogの数を指定できるようにしてみました。 # [ruby-dev:35379]が入るともう少し簡単に書けるんですが。 Index: ext/socket/rubysocket.h =================================================================== --- ext/socket/rubysocket.h (revision 21650) +++ ext/socket/rubysocket.h (working copy) @@ -215,4 +215,10 @@ VALUE s_accept(VALUE klass, int fd, stru VALUE s_accept_nonblock(VALUE klass, rb_io_t *fptr, struct sockaddr *sockaddr, socklen_t *len); +struct sock_svrinit_options { + int backlog; +}; +int sock_svrinit_opt(VALUE arg, struct sock_svrinit_options *opt); +VALUE sock_svrinit(VALUE sock, const struct sock_svrinit_options *opt); + void Init_basicsocket(void); void Init_ipsocket(void); Index: ext/socket/unixserver.c =================================================================== --- ext/socket/unixserver.c (revision 21650) +++ ext/socket/unixserver.c (working copy) @@ -23,7 +23,13 @@ */ static VALUE -unix_svr_init(VALUE sock, VALUE path) +unix_svr_init(int argc, VALUE *argv, VALUE sock) { - return init_unixsock(sock, path, 1); + VALUE path; + struct sock_svrinit_options opt; + + if (argc > 1 && sock_svrinit_opt(argv[argc-1], &opt)) --argc; + if (argc == 1) path = argv[0]; + else rb_scan_args(argc, argv, "1", &path); + return sock_svrinit(init_unixsock(sock, path, 1), &opt); } @@ -140,5 +146,5 @@ Init_unixserver(void) #ifdef HAVE_SYS_UN_H rb_cUNIXServer = rb_define_class("UNIXServer", rb_cUNIXSocket); - rb_define_method(rb_cUNIXServer, "initialize", unix_svr_init, 1); + rb_define_method(rb_cUNIXServer, "initialize", unix_svr_init, -1); rb_define_method(rb_cUNIXServer, "accept", unix_accept, 0); rb_define_method(rb_cUNIXServer, "accept_nonblock", unix_accept_nonblock, 0); Index: ext/socket/tcpserver.c =================================================================== --- ext/socket/tcpserver.c (revision 21650) +++ ext/socket/tcpserver.c (working copy) @@ -28,9 +28,12 @@ tcp_svr_init(int argc, VALUE *argv, VALU { VALUE arg1, arg2; + struct sock_svrinit_options opt; + if (argc > 1 && sock_svrinit_opt(argv[argc-1], &opt)) --argc; if (rb_scan_args(argc, argv, "11", &arg1, &arg2) == 2) - return init_inetsock(sock, arg1, arg2, Qnil, Qnil, INET_SERVER); + sock = init_inetsock(sock, arg1, arg2, Qnil, Qnil, INET_SERVER); else - return init_inetsock(sock, Qnil, arg1, Qnil, Qnil, INET_SERVER); + sock = init_inetsock(sock, Qnil, arg1, Qnil, Qnil, INET_SERVER); + return sock_svrinit(sock, &opt); } Index: ext/socket/ipsocket.c =================================================================== --- ext/socket/ipsocket.c (revision 21650) +++ ext/socket/ipsocket.c (working copy) @@ -101,7 +101,4 @@ init_inetsock_internal(struct inetsock_a arg->fd = -1; - if (type == INET_SERVER) - listen(fd, 5); - /* create new instance */ return init_sock(arg->sock, fd); Index: ext/socket/socket.c =================================================================== --- ext/socket/socket.c (revision 21635) +++ ext/socket/socket.c (working copy) @@ -18,4 +18,33 @@ setup_domain_and_type(VALUE domain, int } +int +sock_svrinit_opt(VALUE arg, struct sock_svrinit_options *opt) +{ + opt->backlog = 5; + if (TYPE(arg) == T_HASH) { + VALUE x; + ID id_listen; + CONST_ID(id_listen, "listen"); + x = rb_hash_lookup(arg, ID2SYM(id_listen)); + if (!NIL_P(x) && (opt->backlog = NUM2INT(x)) < 0) { + rb_raise(rb_eArgError, "negative backlog length: %d", opt->backlog) + } + return Qtrue; + } + return Qfalse; +} + +VALUE +sock_svrinit(VALUE sock, const struct sock_svrinit_options *opt) +{ + rb_io_t *fptr; + + GetOpenFile(sock, fptr); + if (opt->backlog > 0 && listen(fptr->fd, opt->backlog)) { + rb_sys_fail("listen"); + } + return sock; +} + /* * call-seq: Index: ext/socket/unixsocket.c =================================================================== --- ext/socket/unixsocket.c (revision 21650) +++ ext/socket/unixsocket.c (working copy) @@ -66,6 +66,4 @@ init_unixsock(VALUE sock, VALUE path, in } - if (server) listen(fd, 5); - init_sock(sock, fd); if (server) { -- --- 僕の前にBugはない。 --- 僕の後ろにBugはできる。 中田 伸悦