* 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
This commit is contained in:
parent
bd1f4738a4
commit
557802a1da
@ -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>
|
Tue Sep 2 17:02:53 2014 Vit Ondruch <v.ondruch@tiscali.cz>
|
||||||
|
|
||||||
* tool/rbinstall.rb: fixed error of local installation.
|
* tool/rbinstall.rb: fixed error of local installation.
|
||||||
|
69
process.c
69
process.c
@ -3173,6 +3173,43 @@ chfunc_protect(VALUE arg)
|
|||||||
#define O_BINARY 0
|
#define O_BINARY 0
|
||||||
#endif
|
#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
|
* Forks child process, and returns the process ID in the parent
|
||||||
* process.
|
* process.
|
||||||
@ -3206,11 +3243,6 @@ retry_fork(int *status, int *ep, int chfunc_is_async_signal_safe)
|
|||||||
int state = 0;
|
int state = 0;
|
||||||
int try_gc = 1;
|
int try_gc = 1;
|
||||||
|
|
||||||
#define prefork() ( \
|
|
||||||
rb_io_flush(rb_stdout), \
|
|
||||||
rb_io_flush(rb_stderr) \
|
|
||||||
)
|
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
prefork();
|
prefork();
|
||||||
if (!chfunc_is_async_signal_safe)
|
if (!chfunc_is_async_signal_safe)
|
||||||
@ -3223,32 +3255,7 @@ retry_fork(int *status, int *ep, int chfunc_is_async_signal_safe)
|
|||||||
if (0 < pid) /* fork succeed, parent process */
|
if (0 < pid) /* fork succeed, parent process */
|
||||||
return pid;
|
return pid;
|
||||||
/* fork failed */
|
/* fork failed */
|
||||||
switch (errno) {
|
if (handle_fork_error(status, ep, &state, &try_gc))
|
||||||
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;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user