From: Hidetoshi NAGAI Date: 2003-11-05T17:05:03+09:00 Subject: [ruby-dev:21835] Re: pthread trouble on tcltklib 永井@知能.九工大です. From: Hidetoshi NAGAI Subject: [ruby-dev:21833] pthread trouble on tcltklib (Re: ruby-tk hangs when exception is raised) Date: Wed, 5 Nov 2003 12:46:50 +0900 Message-ID: <20031105.124645.74739734.nagai@ai.kyutech.ac.jp> > tcltklib.c 側での対処をあきらめて, > Ruby 本体の eval.c と signal.c への patch として作ってみました. > これで GC や Thread switching が生じても落ちずに済んでいるようです. > とりあえずのテスト用なので,#ifdef などではくくっていません. テストしやすいように,configure --with-pthread-ext で 指定できるように作り直しました. eval.c の方の変更は --with-pthread-ext を指定しない限りは 従来通りのはずです. signal.c の方は変更されてしまいますが,問題は生じないはずです. お試し下さい. Index: configure.in =================================================================== RCS file: /src/ruby/configure.in,v retrieving revision 1.189 diff -u -r1.189 configure.in --- configure.in 31 Oct 2003 03:58:20 -0000 1.189 +++ configure.in 5 Nov 2003 07:56:14 -0000 @@ -323,6 +323,7 @@ if test "$rb_cv_supplementary_lib_c_r" = yes; then MAINLIBS="-lc_r $MAINLIBS" else + AC_DEFINE(HAVE_LIBPTHREAD) MAINLIBS="-pthread $MAINLIBS" CFLAGS="-D_THREAD_SAFE $CFLAGS" fi @@ -663,6 +664,11 @@ dnl default value for $KANJI DEFAULT_KCODE="KCODE_NONE" + +AC_ARG_WITH(pthread-ext, + [ --with-pthread-ext use pthread library on external modules ], + [AC_CHECK_LIB(pthread, pthread_mutex_trylock) + AC_DEFINE(USE_PTHREAD_EXTLIB)]) AC_ARG_WITH(default-kcode, [ --with-default-kcode=CODE specify default value for \$KCODE (utf8|euc|sjis|none)], Index: eval.c =================================================================== RCS file: /src/ruby/eval.c,v retrieving revision 1.583 diff -u -r1.583 eval.c --- eval.c 4 Nov 2003 09:13:56 -0000 1.583 +++ eval.c 5 Nov 2003 07:56:15 -0000 @@ -33,6 +33,10 @@ #include "st.h" #include "dln.h" +#if defined(HAVE_LIBPTHREAD) && defined(USE_PTHREAD_EXTLIB) +#include +#endif + #ifdef __APPLE__ #include #endif @@ -8604,6 +8618,11 @@ return test; } +#if defined(HAVE_LIBPTHREAD) && defined(USE_PTHREAD_EXTLIB) +static pthread_t thid; +static pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER; +#endif + void rb_thread_schedule() { @@ -8620,6 +8639,9 @@ int n, max; int need_select = 0; int select_timeout = 0; +#if defined(HAVE_LIBPTHREAD) && defined(USE_PTHREAD_EXTLIB) + int st; +#endif rb_thread_pending = 0; if (curr_thread == curr_thread->next @@ -8629,6 +8651,16 @@ next = 0; curr = curr_thread; /* starting thread */ +#if defined(HAVE_LIBPTHREAD) && defined(USE_PTHREAD_EXTLIB) + if ((st = pthread_mutex_trylock(&mtx)) == EBUSY) { + if (pthread_self() != thid) { + return; + } + } else { + thid = pthread_self(); + } +#endif + while (curr->status == THREAD_KILLED) { curr = curr->prev; } @@ -8826,12 +8858,22 @@ } next->wait_for = 0; if (next->status == THREAD_RUNNABLE && next == curr_thread) { +#if defined(HAVE_LIBPTHREAD) && defined(USE_PTHREAD_EXTLIB) + if (st != EBUSY) { + pthread_mutex_unlock(& mtx); + } +#endif return; } /* context switch */ if (curr == curr_thread) { if (THREAD_SAVE_CONTEXT(curr)) { +#if defined(HAVE_LIBPTHREAD) && defined(USE_PTHREAD_EXTLIB) + if (st != EBUSY) { + pthread_mutex_unlock(& mtx); + } +#endif return; } } @@ -8841,9 +8883,19 @@ if (!(next->flags & THREAD_TERMINATING)) { next->flags |= THREAD_TERMINATING; /* terminate; execute ensure-clause if any */ +#if defined(HAVE_LIBPTHREAD) && defined(USE_PTHREAD_EXTLIB) + if (st != EBUSY) { + pthread_mutex_unlock(& mtx); + } +#endif rb_thread_restore_context(next, RESTORE_FATAL); } } +#if defined(HAVE_LIBPTHREAD) && defined(USE_PTHREAD_EXTLIB) + if (st != EBUSY) { + pthread_mutex_unlock(& mtx); + } +#endif rb_thread_restore_context(next, RESTORE_NORMAL); } Index: signal.c =================================================================== RCS file: /src/ruby/signal.c,v retrieving revision 1.48 diff -u -r1.48 signal.c --- signal.c 1 Oct 2003 15:14:22 -0000 1.48 +++ signal.c 5 Nov 2003 07:56:15 -0000 @@ -711,6 +711,7 @@ { #ifndef MACOS_UNUSE_SIGNAL VALUE mSignal = rb_define_module("Signal"); + VALUE oldsig; rb_define_global_function("trap", sig_trap, -1); rb_define_module_function(mSignal, "trap", sig_trap, -1); @@ -741,6 +742,21 @@ #endif #ifdef SIGPIPE install_sighandler(SIGPIPE, sigpipe); +#endif + +#ifdef SIGCLD + oldsig = rb_funcall(rb_mKernel, rb_intern("trap"), 2, + INT2FIX(SIGCLD), rb_str_new2("SIG_DFL")); + if (oldsig != Qnil) { + rb_funcall(rb_mKernel, rb_intern("trap"), 2, INT2FIX(SIGCLD), oldsig); + } +#endif +#ifdef SIGCHLD + oldsig = rb_funcall(rb_mKernel, rb_intern("trap"), 2, + INT2FIX(SIGCHLD), rb_str_new2("SIG_DFL")); + if (oldsig != Qnil) { + rb_funcall(rb_mKernel, rb_intern("trap"), 2, INT2FIX(SIGCHLD), oldsig); + } #endif #endif /* MACOS_UNUSE_SIGNAL */ } -- 永井 秀利 (九工大 知能情報) nagai@ai.kyutech.ac.jp