1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

process.c: retry fork if ENOMEM

* process.c (retry_fork): retry with GC if ENOMEM occurred, to free
  swap/kernel space.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@42618 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
nobu 2013-08-19 08:01:26 +00:00
parent 5a096eddb3
commit 7f9f6c3122
2 changed files with 18 additions and 7 deletions

View file

@ -1,3 +1,8 @@
Mon Aug 19 17:00:53 2013 Nobuyoshi Nakada <nobu@ruby-lang.org>
* process.c (retry_fork): retry with GC if ENOMEM occurred, to free
swap/kernel space.
Mon Aug 19 13:28:47 2013 NAKAMURA Usaku <usa@ruby-lang.org> Mon Aug 19 13:28:47 2013 NAKAMURA Usaku <usa@ruby-lang.org>
* include/ruby/win32.h (CLOCK_MONOTONIC): typo. * include/ruby/win32.h (CLOCK_MONOTONIC): typo.

View file

@ -3246,6 +3246,7 @@ retry_fork(int *status, int *ep, int chfunc_is_async_signal_safe)
{ {
rb_pid_t pid; rb_pid_t pid;
int state = 0; int state = 0;
int try_gc = 1;
#define prefork() ( \ #define prefork() ( \
rb_io_flush(rb_stdout), \ rb_io_flush(rb_stdout), \
@ -3265,6 +3266,12 @@ retry_fork(int *status, int *ep, int chfunc_is_async_signal_safe)
return pid; return pid;
/* fork failed */ /* fork failed */
switch (errno) { switch (errno) {
case ENOMEM:
if (try_gc-- > 0 && !rb_during_gc()) {
rb_gc();
continue;
}
break;
case EAGAIN: case EAGAIN:
#if defined(EWOULDBLOCK) && EWOULDBLOCK != EAGAIN #if defined(EWOULDBLOCK) && EWOULDBLOCK != EAGAIN
case EWOULDBLOCK: case EWOULDBLOCK:
@ -3278,14 +3285,13 @@ retry_fork(int *status, int *ep, int chfunc_is_async_signal_safe)
if (status) *status = state; if (status) *status = state;
if (!state) continue; if (!state) continue;
} }
/* fall through */ break;
default:
if (ep) {
preserving_errno((close(ep[0]), close(ep[1])));
}
if (state && !status) rb_jump_tag(state);
return -1;
} }
if (ep) {
preserving_errno((close(ep[0]), close(ep[1])));
}
if (state && !status) rb_jump_tag(state);
return -1;
} }
} }