diff options
author | akr <akr@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2014-09-02 11:47:35 +0000 |
---|---|---|
committer | akr <akr@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2014-09-02 11:47:35 +0000 |
commit | 557802a1daec5fd3d33f42ddb974b0739a081ecb (patch) | |
tree | 88034ca99f6f4a2be691a2c74504c100e3a4dc10 | |
parent | bd1f4738a443a196203d51ee95f137fe7e688311 (diff) | |
download | ruby-557802a1daec5fd3d33f42ddb974b0739a081ecb.tar.gz |
* process.c (handle_fork_error): Extracted from retry_fork.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@47351 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r-- | ChangeLog | 4 | ||||
-rw-r--r-- | process.c | 71 |
2 files changed, 43 insertions, 32 deletions
@@ -1,3 +1,7 @@ +Tue Sep 2 19:48:26 2014 Tanaka Akira <akr@fsij.org> + + * process.c (handle_fork_error): Extracted from retry_fork. + Tue Sep 2 17:02:53 2014 Vit Ondruch <v.ondruch@tiscali.cz> * tool/rbinstall.rb: fixed error of local installation. @@ -3173,6 +3173,43 @@ chfunc_protect(VALUE arg) #define O_BINARY 0 #endif +static int +handle_fork_error(int *status, int *ep, int *state_p, int *try_gc_p) +{ + switch (errno) { + case ENOMEM: + if ((*try_gc_p)-- > 0 && !rb_during_gc()) { + rb_gc(); + return 0; + } + break; + case EAGAIN: +#if defined(EWOULDBLOCK) && EWOULDBLOCK != EAGAIN + case EWOULDBLOCK: +#endif + if (!status && !ep) { + rb_thread_sleep(1); + return 0; + } + else { + rb_protect((VALUE (*)())rb_thread_sleep, 1, state_p); + if (status) *status = *state_p; + if (!*state_p) return 0; + } + break; + } + if (ep) { + preserving_errno((close(ep[0]), close(ep[1]))); + } + if (*state_p && !status) rb_jump_tag(*state_p); + return -1; +} + +#define prefork() ( \ + rb_io_flush(rb_stdout), \ + rb_io_flush(rb_stderr) \ + ) + /* * Forks child process, and returns the process ID in the parent * process. @@ -3206,11 +3243,6 @@ retry_fork(int *status, int *ep, int chfunc_is_async_signal_safe) int state = 0; int try_gc = 1; -#define prefork() ( \ - rb_io_flush(rb_stdout), \ - rb_io_flush(rb_stderr) \ - ) - while (1) { prefork(); if (!chfunc_is_async_signal_safe) @@ -3223,33 +3255,8 @@ retry_fork(int *status, int *ep, int chfunc_is_async_signal_safe) if (0 < pid) /* fork succeed, parent process */ return pid; /* fork failed */ - switch (errno) { - case ENOMEM: - if (try_gc-- > 0 && !rb_during_gc()) { - rb_gc(); - continue; - } - break; - case EAGAIN: -#if defined(EWOULDBLOCK) && EWOULDBLOCK != EAGAIN - case EWOULDBLOCK: -#endif - if (!status && !ep) { - rb_thread_sleep(1); - continue; - } - else { - rb_protect((VALUE (*)())rb_thread_sleep, 1, &state); - if (status) *status = state; - if (!state) continue; - } - break; - } - if (ep) { - preserving_errno((close(ep[0]), close(ep[1]))); - } - if (state && !status) rb_jump_tag(state); - return -1; + if (handle_fork_error(status, ep, &state, &try_gc)) + return -1; } } |