summaryrefslogtreecommitdiff
path: root/process.c
diff options
context:
space:
mode:
authornobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2015-09-08 07:15:09 +0000
committernobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2015-09-08 07:15:09 +0000
commitd3022c424cffc1e92b751e72fb450408e853e388 (patch)
tree2a57e491e48d932adca7eea49b0a35d22a59b591 /process.c
parent2a87a0fc732b7a6168cbf004bdfd6aba74e17586 (diff)
process.c: keep GVL if WNOHANG
* process.c (rb_waitpid): do not release GVL when WNOHANG is set, it should return immediately without blocking. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@51793 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'process.c')
-rw-r--r--process.c30
1 files changed, 19 insertions, 11 deletions
diff --git a/process.c b/process.c
index d3a1596..f915ff6 100644
--- a/process.c
+++ b/process.c
@@ -846,20 +846,23 @@ struct waitpid_arg {
int *st;
};
-static void *
-rb_waitpid_blocking(void *data)
+static rb_pid_t
+do_waitpid(rb_pid_t pid, int *st, int flags)
{
- rb_pid_t result;
- struct waitpid_arg *arg = data;
-
#if defined HAVE_WAITPID
- result = waitpid(arg->pid, arg->st, arg->flags);
+ return waitpid(pid, st, flags);
#elif defined HAVE_WAIT4
- result = wait4(arg->pid, arg->st, arg->flags, NULL);
+ return wait4(pid, st, flags, NULL);
#else
# error waitpid or wait4 is required.
#endif
+}
+static void *
+rb_waitpid_blocking(void *data)
+{
+ struct waitpid_arg *arg = data;
+ rb_pid_t result = do_waitpid(arg->pid, arg->st, arg->flags);
return (void *)(VALUE)result;
}
@@ -881,10 +884,15 @@ rb_waitpid(rb_pid_t pid, int *st, int flags)
{
rb_pid_t result;
- while ((result = do_waitpid_nonblocking(pid, st, flags)) < 0 &&
- (errno == EINTR)) {
- rb_thread_t *th = GET_THREAD();
- RUBY_VM_CHECK_INTS(th);
+ if (flags & WNOHANG) {
+ result = do_waitpid(pid, st, flags);
+ }
+ else {
+ while ((result = do_waitpid_nonblocking(pid, st, flags)) < 0 &&
+ (errno == EINTR)) {
+ rb_thread_t *th = GET_THREAD();
+ RUBY_VM_CHECK_INTS(th);
+ }
}
if (result > 0) {
rb_last_status_set(*st, result);