[#4567] Re: What's the biggest Ruby development? — Aleksi Niemel<aleksi.niemela@...>

Dave said:

18 messages 2000/08/23
[#4568] Q's on Marshal — Robert Feldt <feldt@...> 2000/08/23

[#4580] RubyUnit testcase run for different init params? — Robert Feldt <feldt@...> 2000/08/25

[#4584] Re: RubyUnit testcase run for different init params? — Dave Thomas <Dave@...> 2000/08/25

Robert Feldt <feldt@ce.chalmers.se> writes:

[#4623] Re: RubyUnit testcase run for different init params? — Robert Feldt <feldt@...> 2000/08/28

On Sat, 26 Aug 2000, Dave Thomas wrote:

[#4652] Andy and Dave's European Tour 2000 — Dave Thomas <Dave@...>

24 messages 2000/08/30
[#4653] Re: Andy and Dave's European Tour 2000 — matz@... (Yukihiro Matsumoto) 2000/08/30

Hi,

[#4657] Ruby tutorials for newbie — Kevin Liang <kevin@...> 2000/08/30

Hi,

[ruby-talk:4557] New feature: Process.waitall

From: Brian Fundakowski Feldman <green@...>
Date: 2000-08-23 02:32:41 UTC
List: ruby-talk #4557
Okay, I figured that I wanted a new routine that really had all of the
semantics I thought were useful :)  Also, I needed the W* functions.
Check this out:

irb(main):001:0> (0..4).each {|c| fork { sleep 1 + 2 * c; exit c}}
0..4
irb(main):002:0> x = Process.waitall
[[34040, 0], [34041, 256], [34042, 512], [34043, 768], [34044, 1024]]
irb(main):003:0> x.each {|p| p Process.wexitstatus p[1]}
0
1
2
3
4
[[34040, 0], [34041, 256], [34042, 512], [34043, 768], [34044, 1024]]

Neat? :)

I've included the implementation (in diff -u format).  I've not tested
the NO_WAITPID case since I don't have a "no waitpid" machine, but I
think I did the code correctly for that.

--
 Brian Fundakowski Feldman           \  FreeBSD: The Power to Serve!  /
 green@FreeBSD.org                    `------------------------------'

Attachments (1)

patch-aa (4.45 KB, text/plain)
--- process.c.orig	Mon Jul 24 03:16:13 2000
+++ process.c	Tue Aug 22 22:24:57 2000
@@ -157,6 +157,30 @@
     data->status = value;
     return ST_DELETE;
 }
+
+struct waitall_data {
+    int pid;
+    int status;
+    VALUE ary;
+}
+
+static int
+waitall_each(key, value, data)
+    int key, value;
+    struct wait_data *data;
+{
+    VALUE pid_status_member;
+
+    if (data->status != -1) return ST_STOP;
+
+    data->pid = key;
+    data->status = value;
+    pid_status_member = rb_ary_new2(2);
+    rb_ary_push(pid_status_member, INT2NUM(key));
+    rb_ary_push(pid_status_member, INT2NUM(value));
+    rb_ary_push(data->ary, pid_status_member);
+    return ST_DELETE;
+}
 #endif
 
 static VALUE
@@ -189,6 +213,58 @@
 }
 
 static VALUE
+rb_f_waitall()
+{
+    VALUE pid_status_ary, pid_status_member;
+    int pid, state;
+#ifdef NO_WAITPID
+    struct waitall_data data;
+
+    data.ary = pid_status_ary = rb_ary_new();
+    data.status = -1;
+    st_foreach(pid_tbl, waitall_each, &data);
+    if (data.status != -1) {
+	rb_last_status = data.status;
+	return pid_status_ary;
+    }
+
+    for (pid = -1;;) {
+	pid = wait(&state);
+	if (pid == -1) {
+	    if (errno == ECHILD)
+		break;
+            if (errno == EINTR) {
+		rb_thread_schedule();
+		continue;
+	    }
+	    rb_sys_fail(0);
+	}
+	pid_status_member = rb_ary_new2(2);
+	rb_ary_push(pid_status_member, INT2NUM(pid));
+	rb_ary_push(pid_status_member, INT2NUM(state));
+	rb_ary_push(pid_status_ary, pid_status_member);
+    }
+    if (RARRAY(pid_status_ary)->len != 0)
+	rb_last_status = INT2FIX(state);
+#else
+    pid_status_ary = rb_ary_new();
+    for (pid = -1;;) {
+	pid = rb_waitpid(-1, 0, &state);
+	if (pid == -1) {
+	    if (errno == ECHILD)
+		break;
+	    rb_sys_fail(0);
+	}
+	pid_status_member = rb_ary_new2(2);
+	rb_ary_push(pid_status_member, INT2NUM(pid));
+	rb_ary_push(pid_status_member, INT2NUM(state));
+	rb_ary_push(pid_status_ary, pid_status_member);
+    }
+#endif
+    return pid_status_ary;
+}
+
+static VALUE
 rb_f_waitpid(obj, vpid, vflags)
     VALUE obj, vpid, vflags;
 {
@@ -203,6 +279,83 @@
     return INT2FIX(pid);
 }
 
+static VALUE
+rb_f_wifstopped(obj, statusnum)
+    VALUE obj, statusnum;
+{
+    int status = NUM2INT(statusnum);
+
+    if (WIFSTOPPED(status))
+	return Qtrue;
+    else
+	return Qfalse;
+}
+
+static VALUE
+rb_f_wstopsig(obj, statusnum)
+    VALUE obj, statusnum;
+{
+    int status = NUM2INT(statusnum);
+
+    return INT2NUM(WSTOPSIG(status));
+}
+
+static VALUE
+rb_f_wifsignaled(obj, statusnum)
+    VALUE obj, statusnum;
+{
+    int status = NUM2INT(statusnum);
+
+    if (WIFSIGNALED(status))
+	return Qtrue;
+    else
+	return Qfalse;
+}
+
+static VALUE
+rb_f_wtermsig(obj, statusnum)
+    VALUE obj, statusnum;
+{
+    int status = NUM2INT(statusnum);
+
+    return INT2NUM(WTERMSIG(status));
+}
+
+static VALUE
+rb_f_wifexited(obj, statusnum)
+    VALUE obj, statusnum;
+{
+    int status = NUM2INT(statusnum);
+
+    if (WIFEXITED(status))
+	return Qtrue;
+    else
+	return Qfalse;
+}
+
+static VALUE
+rb_f_wexitstatus(obj, statusnum)
+    VALUE obj, statusnum;
+{
+    int status = NUM2INT(statusnum);
+
+    return INT2NUM(WEXITSTATUS(status));
+}
+
+#ifdef WCOREDUMP
+static VALUE
+rb_f_wcoredump(obj, statusnum)
+    VALUE obj, statusnum;
+{
+    int status = NUM2INT(statusnum);
+
+    if (WCOREDUMP(status))
+	return Qtrue;
+    else
+	return Qfalse;
+}
+#endif
+
 char *strtok();
 
 #ifdef HAVE_SETITIMER
@@ -1053,7 +1206,17 @@
 #endif
 #ifndef NT
     rb_define_module_function(rb_mProcess, "wait", rb_f_wait, 0);
+    rb_define_module_function(rb_mProcess, "waitall", rb_f_waitall, 0);
     rb_define_module_function(rb_mProcess, "waitpid", rb_f_waitpid, 2);
+    rb_define_module_function(rb_mProcess, "wifstopped", rb_f_wifstopped, 1);
+    rb_define_module_function(rb_mProcess, "wstopsig", rb_f_wstopsig, 1);
+    rb_define_module_function(rb_mProcess, "wifsignaled", rb_f_wifsignaled, 1);
+    rb_define_module_function(rb_mProcess, "wtermsig", rb_f_wtermsig, 1);
+    rb_define_module_function(rb_mProcess, "wifexited", rb_f_wifexited, 1);
+    rb_define_module_function(rb_mProcess, "wexitstatus", rb_f_wexitstatus, 1);
+#ifdef WCOREDUMP
+    rb_define_module_function(rb_mProcess, "wcoredump", rb_f_wcoredump, 1);
+#endif
 
 #ifndef USE_CWGUSI
     rb_define_module_function(rb_mProcess, "pid", get_pid, 0);

In This Thread

Prev Next