Project

General

Profile

Backport #2739 » 0001-backport-ruby_1_8-26371.patch

kosaki (Motohiro KOSAKI), 03/09/2010 02:28 AM

View differences:

ChangeLog
Fri Jan 22 01:22:27 2010 NAKAMURA Usaku <usa@ruby-lang.org>
* eval.c (thread_timer, rb_thread_stop_timer): check the timing of
stopping timer. patch from KOSAKI Motohiro <kosaki.motohiro _AT_
jp.fujitsu.com>
* eval.c (rb_thread_start_timer): NetBSD5 seems to be hung when calling
pthread_create() from pthread_atfork()'s parent handler.
* io.c (pipe_open): workaround for NetBSD5. stop timer thread before
fork(), and start it if needed.
* process.c (rb_f_fork, rb_f_system): ditto.
fixed [ruby-dev:40074]
Sun Jan 10 19:00:31 2010 Nobuyoshi Nakada <nobu@ruby-lang.org>
* lib/webrick/accesslog.rb : Escape needed.
eval.c
pthread_t thread;
} time_thread = {PTHREAD_COND_INITIALIZER, PTHREAD_MUTEX_INITIALIZER};
static int timer_stopping;
#define safe_mutex_lock(lock) \
pthread_mutex_lock(lock); \
pthread_cleanup_push((void (*)_((void *)))pthread_mutex_unlock, lock)
......
#define WAIT_FOR_10MS() \
pthread_cond_timedwait(&running->cond, &running->lock, get_ts(&to, PER_NANO/100))
while ((err = WAIT_FOR_10MS()) == EINTR || err == ETIMEDOUT) {
if (timer_stopping)
break;
if (!rb_thread_critical) {
rb_thread_pending = 1;
if (rb_trap_immediate) {
......
safe_mutex_lock(&time_thread.lock);
if (pthread_create(&time_thread.thread, 0, thread_timer, args) == 0) {
thread_init = 1;
#ifndef __NetBSD__
pthread_atfork(0, 0, rb_thread_stop_timer);
#endif
pthread_cond_wait(&start, &time_thread.lock);
}
pthread_cleanup_pop(1);
......
{
if (!thread_init) return;
safe_mutex_lock(&time_thread.lock);
timer_stopping = 1;
pthread_cond_signal(&time_thread.cond);
thread_init = 0;
pthread_cleanup_pop(1);
pthread_join(time_thread.thread, NULL);
timer_stopping = 0;
}
#elif defined(HAVE_SETITIMER)
static void
io.c
}
retry:
#ifdef __NetBSD__
rb_thread_stop_timer();
#endif
switch ((pid = fork())) {
case 0: /* child */
if (modef & FMODE_READABLE) {
......
ruby_sourcefile, ruby_sourceline, pname);
_exit(127);
}
#ifdef __NetBSD__
rb_thread_start_timer();
#endif
rb_io_synchronized(RFILE(orig_stdout)->fptr);
rb_io_synchronized(RFILE(orig_stderr)->fptr);
return Qnil;
case -1: /* fork failed */
#ifdef __NetBSD__
rb_thread_start_timer();
#endif
if (errno == EAGAIN) {
rb_thread_sleep(1);
goto retry;
......
break;
default: /* parent */
#ifdef __NetBSD__
rb_thread_start_timer();
#endif
if (pid < 0) rb_sys_fail(pname);
else {
VALUE port = io_alloc(rb_cIO);
process.c
fflush(stderr);
#endif
#ifdef __NetBSD__
before_exec();
pid = fork();
after_exec();
switch (pid) {
#else
switch (pid = fork()) {
#endif
case 0:
#ifdef linux
after_exec();
......
chfunc = signal(SIGCHLD, SIG_DFL);
retry:
#ifdef __NetBSD__
before_exec();
#endif
pid = fork();
if (pid == 0) {
/* child process */
......
rb_protect(proc_exec_args, (VALUE)&earg, NULL);
_exit(127);
}
#ifdef __NetBSD__
after_exec();
#endif
if (pid < 0) {
if (errno == EAGAIN) {
rb_thread_sleep(1);
(1-1/2)