ruby-changes:11091
From: nobu <ko1@a...>
Date: Sun, 1 Mar 2009 16:19:50 +0900 (JST)
Subject: [ruby-changes:11091] Ruby:r22688 (trunk): * process.c (rb_waitpid): use wait_each() on no waitpid platforms.
nobu 2009-03-01 16:15:33 +0900 (Sun, 01 Mar 2009) New Revision: 22688 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=22688 Log: * process.c (rb_waitpid): use wait_each() on no waitpid platforms. [ruby-dev:38054] Modified files: trunk/ChangeLog trunk/process.c Index: ChangeLog =================================================================== --- ChangeLog (revision 22687) +++ ChangeLog (revision 22688) @@ -1,3 +1,8 @@ +Sun Mar 1 16:15:31 2009 Nobuyoshi Nakada <nobu@r...> + + * process.c (rb_waitpid): use wait_each() on no waitpid platforms. + [ruby-dev:38054] + Sun Mar 1 16:01:01 2009 Nobuyoshi Nakada <nobu@r...> * process.c (proc_daemon): stops and restarts timer thread because Index: process.c =================================================================== --- process.c (revision 22687) +++ process.c (revision 22688) @@ -590,6 +590,29 @@ #if !defined(HAVE_WAITPID) && !defined(HAVE_WAIT4) #define NO_WAITPID static st_table *pid_tbl; + +struct wait_data { + rb_pid_t pid; + int status; +}; + +static int +wait_each(rb_pid_t pid, int status, struct wait_data *data) +{ + if (data->status != -1) return ST_STOP; + + data->pid = pid; + data->status = status; + return ST_DELETE; +} + +static int +waitall_each(rb_pid_t pid, int status, VALUE ary) +{ + rb_last_status_set(status, pid); + rb_ary_push(ary, rb_assoc_new(PIDT2NUM(pid), rb_last_status_get())); + return ST_DELETE; +} #else struct waitpid_arg { rb_pid_t pid; @@ -624,7 +647,7 @@ #ifndef NO_WAITPID struct waitpid_arg arg; -retry: + retry: arg.pid = pid; arg.st = st; arg.flags = flags; @@ -635,13 +658,25 @@ RUBY_VM_CHECK_INTS(); goto retry; } - return -1; + return (rb_pid_t)-1; } #else /* NO_WAITPID */ - if (pid_tbl && st_lookup(pid_tbl, pid, (st_data_t *)st)) { - rb_last_status_set(*st, pid); - st_delete(pid_tbl, (st_data_t*)&pid, NULL); - return pid; + if (pid_tbl) { + st_data_t status, piddata = (st_data_t)pid; + if (pid == (rb_pid_t)-1) { + struct wait_data data; + data.pid = (rb_pid_t)-1; + data.status = -1; + st_foreach(pid_tbl, wait_each, (st_data_t)&data); + if (data.status != -1) { + rb_last_status_set(data.status, data.pid); + return data.pid; + } + } + else if (st_delete(pid_tbl, &piddata, &status)) { + rb_last_status_set(*st = (int)status, pid); + return pid; + } } if (flags) { @@ -656,13 +691,13 @@ rb_thread_schedule(); continue; } - return -1; + return (rb_pid_t)-1; } - if (result == pid) { + if (result == pid || pid == (rb_pid_t)-1) { break; } if (!pid_tbl) - pid_tbl = st_init_numtable(); + pid_tbl = st_init_numtable(); st_insert(pid_tbl, pid, (st_data_t)st); if (!rb_thread_alone()) rb_thread_schedule(); } @@ -673,32 +708,7 @@ return result; } -#ifdef NO_WAITPID -struct wait_data { - rb_pid_t pid; - int status; -}; -static int -wait_each(rb_pid_t pid, int status, struct wait_data *data) -{ - if (data->status != -1) return ST_STOP; - - data->pid = pid; - data->status = status; - return ST_DELETE; -} - -static int -waitall_each(rb_pid_t pid, int status, VALUE ary) -{ - rb_last_status_set(status, pid); - rb_ary_push(ary, rb_assoc_new(PIDT2NUM(pid), rb_last_status_get())); - return ST_DELETE; -} -#endif - - /* [MG]:FIXME: I wasn't sure how this should be done, since ::wait() has historically been documented as if it didn't take any arguments despite the fact that it's just an alias for ::waitpid(). The way I -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/