summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornagai <nagai@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2003-11-05 14:00:11 +0000
committernagai <nagai@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2003-11-05 14:00:11 +0000
commitea03c3fc2c0bfcf6351c3bce9496fd4607f4594a (patch)
tree6c121bf51ead591584872b4674497d233f7b37b5
parent4dada1c8a20c0fab0e058d7cd934c1c011617049 (diff)
configure.in, eval.c, signal.c: : add '--with-pthread-ext' option
to fix the pthread trouble on 'tcltklib' ext/tcltklib/README.1st: add the description of '--with-pthread-ext' ext/tk/lib/tktext.rb : add TkText#text_copy, text_cut, text_paste to support Tcl/Tk8.4's tk_textCopy, tk_textCut, tk_textPaste ext/tk/lib/tk.rb : add TkMenu#set_focus support Tcl/Tk's tk_menuSetFocus git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@4904 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r--ChangeLog13
-rw-r--r--configure.in6
-rw-r--r--eval.c42
-rw-r--r--ext/tcltklib/README.1st7
-rw-r--r--ext/tk/lib/tk.rb7
-rw-r--r--ext/tk/lib/tktext.rb15
-rw-r--r--signal.c50
7 files changed, 140 insertions, 0 deletions
diff --git a/ChangeLog b/ChangeLog
index 8ce17bfd32..2a92d69d9e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,16 @@
+Wed Nov 5 22:55:16 2003 Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>
+
+ * configure.in, eval.c, signal.c: : add '--with-pthread-ext'
+ option to fix the pthread trouble on 'tcltklib'
+
+ * ext/tcltklib/README.1st: add the description of '--with-pthread-ext'
+
+ * ext/tk/lib/tktext.rb : add TkText#text_copy, text_cut, text_paste
+ to support Tcl/Tk8.4's tk_textCopy, tk_textCut, tk_textPaste
+
+ * ext/tk/lib/tk.rb : add TkMenu#set_focus support Tcl/Tk's
+ tk_menuSetFocus
+
Wed Nov 5 19:08:47 2003 Nobuyoshi Nakada <nobu@ruby-lang.org>
* lib/optparse.rb (OptionParser::Switch::PlacedArgument::parse):
diff --git a/configure.in b/configure.in
index e1380f9b3b..2f66c572d7 100644
--- a/configure.in
+++ b/configure.in
@@ -323,6 +323,7 @@ freebsd*) LIBS="-lm $LIBS"
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
@@ -664,6 +665,11 @@ AC_DEFINE_UNQUOTED(STACK_GROW_DIRECTION, $rb_cv_stack_grow_dir)
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)],
[case $withval in
diff --git a/eval.c b/eval.c
index 98e75e933b..f8543a41f9 100644
--- a/eval.c
+++ b/eval.c
@@ -33,6 +33,10 @@
#include "st.h"
#include "dln.h"
+#if defined(HAVE_LIBPTHREAD) && defined(USE_PTHREAD_EXTLIB)
+#include <pthread.h>
+#endif
+
#ifdef __APPLE__
#include <crt_externs.h>
#endif
@@ -8604,6 +8608,11 @@ find_bad_fds(dst, src, max)
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 +8629,9 @@ rb_thread_schedule()
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 +8641,16 @@ rb_thread_schedule()
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 +8848,22 @@ rb_thread_schedule()
}
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 +8873,19 @@ rb_thread_schedule()
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);
}
diff --git a/ext/tcltklib/README.1st b/ext/tcltklib/README.1st
index 14c56fd410..fe965e04d0 100644
--- a/ext/tcltklib/README.1st
+++ b/ext/tcltklib/README.1st
@@ -29,5 +29,12 @@ directry of Ruby sources, please try something like as the followings.
$ rm Makefile
$ CONFIGURE_ARGS='--with-tcl-include=/usr/local/include/tcl8.3/ --with-tcllib=tcl8.3 --with-tklib=tk8.3 --enable-tcltk_stubs' ruby extconf.rb
+
+ *** ATTENTION ***
+If your Tcl/Tk libraries are compiled with "pthread support", Ruby/Tk
+may cause "Hang-up" or "Segmentation Fault" frequently. To avoid this
+trouble, please try to use the '--with-pthread-ext' option of the
+'configure' command and re-compile Ruby sources.
+
==========================================================
Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)
diff --git a/ext/tk/lib/tk.rb b/ext/tk/lib/tk.rb
index 9cdd3b918e..e5d1c6f63b 100644
--- a/ext/tk/lib/tk.rb
+++ b/ext/tk/lib/tk.rb
@@ -4289,6 +4289,10 @@ class TkWindow<TkObject
self
end
+ def caret(keys=nil)
+ TkXIM.caret(path, keys)
+ end
+
def destroy
super
children = []
@@ -5400,6 +5404,9 @@ class TkMenu<TkWindow
configure_cmd 'postcommand', cmd
self
end
+ def set_focus
+ tk_call('tk_menuSetFocus', path)
+ end
def tearoffcommand(cmd=Proc.new)
configure_cmd 'tearoffcommand', cmd
self
diff --git a/ext/tk/lib/tktext.rb b/ext/tk/lib/tktext.rb
index 109afad924..8ab57d8065 100644
--- a/ext/tk/lib/tktext.rb
+++ b/ext/tk/lib/tktext.rb
@@ -284,6 +284,21 @@ class TkText<TkTextWin
self
end
+ def text_copy
+ # Tk8.4 feature
+ tk_call('tk_textCopy', @path)
+ end
+
+ def text_cut
+ # Tk8.4 feature
+ tk_call('tk_textCut', @path)
+ end
+
+ def text_paste
+ # Tk8.4 feature
+ tk_call('tk_textPaste', @path)
+ end
+
def tag_add(tag, index1, index2=None)
tk_send 'tag', 'add', tag, index1, index2
self
diff --git a/signal.c b/signal.c
index 628fdc3fc6..4e489a73bb 100644
--- a/signal.c
+++ b/signal.c
@@ -706,6 +706,48 @@ install_sighandler(signum, handler)
}
}
+static void
+init_sigchld(sig)
+ int sig;
+{
+ sighandler_t oldfunc;
+#ifndef _WIN32
+# ifdef HAVE_SIGPROCMASK
+ sigset_t mask;
+# else
+ int mask;
+# endif
+#endif
+
+#ifndef _WIN32
+ /* disable interrupt */
+# ifdef HAVE_SIGPROCMASK
+ sigfillset(&mask);
+ sigprocmask(SIG_BLOCK, &mask, &mask);
+# else
+ mask = sigblock(~0);
+# endif
+#endif
+
+ oldfunc = ruby_signal(sig, SIG_DFL);
+ if (oldfunc != SIG_DFL && oldfunc != SIG_IGN) {
+ ruby_signal(sig, oldfunc);
+ } else {
+ trap_list[sig] = 0;
+ }
+
+#ifndef _WIN32
+#ifdef HAVE_SIGPROCMASK
+ sigdelset(&mask, sig);
+ sigprocmask(SIG_SETMASK, &mask, NULL);
+#else
+ mask &= ~sigmask(sig);
+ sigsetmask(mask);
+#endif
+ trap_last_mask = mask;
+#endif
+}
+
void
Init_signal()
{
@@ -742,5 +784,13 @@ Init_signal()
#ifdef SIGPIPE
install_sighandler(SIGPIPE, sigpipe);
#endif
+
+#ifdef SIGCLD
+ init_sigchld(SIGCLD);
+#endif
+#ifdef SIGCHLD
+ init_sigchld(SIGCHLD);
+#endif
+
#endif /* MACOS_UNUSE_SIGNAL */
}