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
Родитель 5a096eddb3
Коммит 7f9f6c3122
2 изменённых файлов: 18 добавлений и 7 удалений

Просмотреть файл

@ -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>
* include/ruby/win32.h (CLOCK_MONOTONIC): typo.

Просмотреть файл

@ -3246,6 +3246,7 @@ retry_fork(int *status, int *ep, int chfunc_is_async_signal_safe)
{
rb_pid_t pid;
int state = 0;
int try_gc = 1;
#define prefork() ( \
rb_io_flush(rb_stdout), \
@ -3265,6 +3266,12 @@ retry_fork(int *status, int *ep, int chfunc_is_async_signal_safe)
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:
@ -3278,14 +3285,13 @@ retry_fork(int *status, int *ep, int chfunc_is_async_signal_safe)
if (status) *status = state;
if (!state) continue;
}
/* fall through */
default:
if (ep) {
preserving_errno((close(ep[0]), close(ep[1])));
}
if (state && !status) rb_jump_tag(state);
return -1;
break;
}
if (ep) {
preserving_errno((close(ep[0]), close(ep[1])));
}
if (state && !status) rb_jump_tag(state);
return -1;
}
}