From e9e100aa48cfc43a588ee411e1fbb861de956587 Mon Sep 17 00:00:00 2001 From: matz Date: Wed, 24 Dec 2003 08:47:36 +0000 Subject: * eval.c (catch_timer): do not call rb_thread_schedule() inside to avoid pthread_mutex_lock() deadlock. interrupts to system calls are detected by TRAP_END via EINTR error. * eval.c (thread_timer): do not post signal unless it is absolutely necessary. * rubysig.h (TRAP_END): add CHECK_INTS to switch thread. * regex.c (re_compile_pattern): check if nextp is smaller than pend. [ruby-dev:22372] * eval.c (umethod_bind): remove method overridden check. [ruby-dev:22366] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@5279 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ChangeLog | 17 +++++++++++++++++ eval.c | 49 ++++++++++++++++++++++++++++--------------------- io.c | 6 +++--- regex.c | 7 ++++--- rubysig.h | 2 ++ 5 files changed, 54 insertions(+), 27 deletions(-) diff --git a/ChangeLog b/ChangeLog index 2d102daec8..7cb8499c2b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,20 @@ +Wed Dec 24 16:46:08 2003 Yukihiro Matsumoto + + * eval.c (catch_timer): do not call rb_thread_schedule() inside to + avoid pthread_mutex_lock() deadlock. interrupts to system calls + are detected by TRAP_END via EINTR error. + + * eval.c (thread_timer): do not post signal unless it is + absolutely necessary. + + * rubysig.h (TRAP_END): add CHECK_INTS to switch thread. + + * regex.c (re_compile_pattern): check if nextp is smaller than + pend. [ruby-dev:22372] + + * eval.c (umethod_bind): remove method overridden check. + [ruby-dev:22366] + Wed Dec 24 16:13:05 2003 GOTOU Yuuzou * ext/openssl/ossl_ssl.c (ossl_ssl_read): should check for error diff --git a/eval.c b/eval.c index 0e033c2c78..9a6d342e43 100644 --- a/eval.c +++ b/eval.c @@ -7602,10 +7602,12 @@ umethod_bind(method, recv) if (FL_TEST(data->rklass, FL_SINGLETON)) { rb_raise(rb_eTypeError, "singleton method called for a different object"); } +#if 0 if (FL_TEST(CLASS_OF(recv), FL_SINGLETON) && st_lookup(RCLASS(CLASS_OF(recv))->m_tbl, data->oid, 0)) { rb_raise(rb_eTypeError, "method `%s' overridden", rb_id2name(data->oid)); } +#endif if(!rb_obj_is_kind_of(recv, data->rklass)) { rb_raise(rb_eTypeError, "bind argument must be an instance of %s", rb_class2name(data->rklass)); @@ -8417,13 +8419,12 @@ rb_thread_save_context(th) th->stk_len = len; FLUSH_REGISTER_WINDOWS; MEMCPY(th->stk_ptr, th->stk_pos, VALUE, th->stk_len); -#ifdef USE_CONTEXT +#ifdef __ia64__ { ucontext_t ctx; VALUE *top, *bot; getcontext(&ctx); -#ifdef __ia64__ bot = (VALUE*)__libc_ia64_register_backing_store_base; #if defined(__FreeBSD__) top = (VALUE*)ctx.uc_mcontext.mc_special.bspstore; @@ -8433,7 +8434,6 @@ rb_thread_save_context(th) th->bstr_len = top - bot; REALLOC_N(th->bstr_ptr, VALUE, th->bstr_len); MEMCPY(th->bstr_ptr, (VALUE*)__libc_ia64_register_backing_store_base, VALUE, th->bstr_len); -#endif } #endif #ifdef SAVE_WIN32_EXCEPTION_LIST @@ -9535,11 +9535,7 @@ rb_thread_alloc(klass) static int thread_init = 0; -#if defined(HAVE_LIBPTHREAD) && defined(_REENTRANT) -# define PTHREAD_TIMER -#endif - -#if defined(PTHREAD_TIMER) || defined(HAVE_SETITIMER) +#if defined(_THREAD_SAFE) static void catch_timer(sig) int sig; @@ -9547,15 +9543,9 @@ catch_timer(sig) #if !defined(POSIX_SIGNAL) && !defined(BSD_SIGNAL) signal(sig, catch_timer); #endif - if (!rb_thread_critical) { - if (rb_trap_immediate) { - rb_thread_schedule(); - } - else rb_thread_pending = 1; - } + /* cause EINTR */ } -#ifdef PTHREAD_TIMER static pthread_t time_thread; static void* @@ -9568,7 +9558,12 @@ thread_timer(dummy) req.tv_sec = 0; req.tv_nsec = 10000000; nanosleep(&req, &rem); - pthread_kill(ruby_thid, SIGVTALRM); + if (!rb_thread_critical) { + rb_thread_pending = 1; + if (rb_trap_immediate) { + pthread_kill(ruby_thid, SIGVTALRM); + } + } } } @@ -9581,7 +9576,20 @@ void rb_thread_stop_timer() { } -#else /* HAVE_SETITIMER */ +#elif defined(HAVE_SETITIMER) +static void +catch_timer(sig) + int sig; +{ +#if !defined(POSIX_SIGNAL) && !defined(BSD_SIGNAL) + signal(sig, catch_timer); +#endif + if (!rb_thread_critical) { + rb_thread_pending = 1; + } + /* cause EINTR */ +} + void rb_thread_start_timer() { @@ -9605,8 +9613,7 @@ rb_thread_stop_timer() tval.it_value = tval.it_interval; setitimer(ITIMER_VIRTUAL, &tval, NULL); } -#endif -#else /* !(PTHREAD_TIMER || HAVE_SETITIMER) */ +#else /* !(_THREAD_SAFE || HAVE_SETITIMER) */ int rb_thread_tick = THREAD_TICK; #endif @@ -9629,14 +9636,14 @@ rb_thread_start_0(fn, arg, th) if (!thread_init) { thread_init = 1; -#if defined(HAVE_SETITIMER) || defined(PTHREAD_TIMER) +#if defined(HAVE_SETITIMER) || defined(_THREAD_SAFE) #if defined(POSIX_SIGNAL) posix_signal(SIGVTALRM, catch_timer); #else signal(SIGVTALRM, catch_timer); #endif -#ifdef PTHREAD_TIMER +#ifdef _THREAD_SAFE pthread_create(&time_thread, 0, thread_timer, 0); #else rb_thread_start_timer(); diff --git a/io.c b/io.c index a8ab755758..8f9c9d59b9 100644 --- a/io.c +++ b/io.c @@ -247,7 +247,9 @@ rb_io_check_writable(fptr) io_seek(fptr, 0, SEEK_CUR); } #endif - fptr->mode &= ~FMODE_RBUF; + if (!fptr->f2) { + fptr->mode &= ~FMODE_RBUF; + } } int @@ -309,9 +311,7 @@ io_fflush(f, fptr) rb_io_check_closed(fptr); } for (;;) { - TRAP_BEG; n = fflush(f); - TRAP_END; if (n != EOF) break; if (!rb_io_wait_writable(fileno(f))) rb_sys_fail(fptr->path); diff --git a/regex.c b/regex.c index d684eca835..7db560bb98 100644 --- a/regex.c +++ b/regex.c @@ -2373,9 +2373,10 @@ re_compile_pattern(pattern, size, bufp) nextp = p + mbclen(c) - 1; if (!pending_exact || pending_exact + *pending_exact + 1 != b || *pending_exact >= (c1 ? 0176 : 0177) - || *nextp == '+' || *nextp == '?' - || *nextp == '*' || *nextp == '^' - || *nextp == '{') { + || (nextp < pend && + ( *nextp == '+' || *nextp == '?' + || *nextp == '*' || *nextp == '^' + || *nextp == '{'))) { laststart = b; BUFPUSH(exactn); pending_exact = b; diff --git a/rubysig.h b/rubysig.h index 9049325a36..6be634787d 100644 --- a/rubysig.h +++ b/rubysig.h @@ -26,6 +26,7 @@ typedef LONG rb_atomic_t; rb_atomic_t trap_immediate = ATOMIC_SET(rb_trap_immediate, 1) # define TRAP_END\ ATOMIC_SET(rb_trap_immediate, trap_immediate);\ + CHECK_INTS;\ } while (0) # define RUBY_CRITICAL(statements) do {\ rb_w32_enter_critical();\ @@ -44,6 +45,7 @@ typedef int rb_atomic_t; int trap_immediate = rb_trap_immediate;\ rb_trap_immediate = 1 # define TRAP_END rb_trap_immediate = trap_immediate;\ + CHECK_INTS;\ } while (0) # define RUBY_CRITICAL(statements) do {\ -- cgit v1.2.3