changeset 58986:59945307b86b

* syssignal.h: Declare main_thread. (SIGNAL_THREAD_CHECK): New macro. * keyboard.c (input_available_signal): Move thread checking code to macro SIGNAL_THREAD_CHECK and call that macro. (interrupt_signal): Call SIGNAL_THREAD_CHECK. * alloc.c (uninterrupt_malloc): Move main_thread to emacs.c. * emacs.c: Define main_thread. (main): Initialize main_thread. (handle_USR1_signal, handle_USR2_signal, fatal_error_signal) (memory_warning_signal): Call SIGNAL_THREAD_CHECK. * floatfns.c (float_error): Call SIGNAL_THREAD_CHECK. * dispnew.c (window_change_signal): Call SIGNAL_THREAD_CHECK. * sysdep.c (select_alarm): Call SIGNAL_THREAD_CHECK. * process.c (send_process_trap, sigchld_handler): Call SIGNAL_THREAD_CHECK. * data.c (arith_error): Call SIGNAL_THREAD_CHECK. * atimer.c (alarm_signal_handler): Call SIGNAL_THREAD_CHECK.
author Jan Djärv <jan.h.d@swipnet.se>
date Wed, 15 Dec 2004 21:40:41 +0000
parents 0395e55b4aa7
children b24e485e88f7
files src/ChangeLog src/alloc.c src/atimer.c src/data.c src/dispnew.c src/emacs.c src/floatfns.c src/keyboard.c src/process.c src/sysdep.c src/syssignal.h
diffstat 11 files changed, 84 insertions(+), 22 deletions(-) [+]
line wrap: on
line diff
--- a/src/ChangeLog	Wed Dec 15 21:34:14 2004 +0000
+++ b/src/ChangeLog	Wed Dec 15 21:40:41 2004 +0000
@@ -1,5 +1,32 @@
 2004-12-15  Jan Dj,Ad(Brv  <jan.h.d@swipnet.se>
 
+	* syssignal.h: Declare main_thread.
+	(SIGNAL_THREAD_CHECK): New macro.
+
+	* keyboard.c (input_available_signal): Move thread checking code
+	to macro SIGNAL_THREAD_CHECK and call that macro.
+	(interrupt_signal): Call SIGNAL_THREAD_CHECK.
+
+	* alloc.c (uninterrupt_malloc): Move main_thread to emacs.c.
+
+	* emacs.c: Define main_thread.
+	(main): Initialize main_thread.
+	(handle_USR1_signal, handle_USR2_signal, fatal_error_signal)
+	(memory_warning_signal): Call SIGNAL_THREAD_CHECK.
+
+	* floatfns.c (float_error): Call SIGNAL_THREAD_CHECK.
+
+	* dispnew.c (window_change_signal): Call SIGNAL_THREAD_CHECK.
+
+	* sysdep.c (select_alarm): Call SIGNAL_THREAD_CHECK.
+
+	* process.c (send_process_trap, sigchld_handler): Call 
+	SIGNAL_THREAD_CHECK.
+
+	* data.c (arith_error): Call SIGNAL_THREAD_CHECK.
+
+	* atimer.c (alarm_signal_handler): Call SIGNAL_THREAD_CHECK.
+
 	* xterm.c (xg_scroll_callback): Update XG_LAST_SB_DATA before
 	returning when xg_ignore_gtk_scrollbar is true.
 
--- a/src/alloc.c	Wed Dec 15 21:34:14 2004 +0000
+++ b/src/alloc.c	Wed Dec 15 21:40:41 2004 +0000
@@ -99,7 +99,7 @@
    If Emacs sets malloc hooks (! SYSTEM_MALLOC) and the emacs_blocked_*
    functions below are called from malloc, there is a chance that one
    of these threads preempts the Emacs main thread and the hook variables
-   end up in a inconsistent state.  So we have a mutex to prevent that (note
+   end up in an inconsistent state.  So we have a mutex to prevent that (note
    that the backend handles concurrent access to malloc within its own threads
    but Emacs code running in the main thread is not included in that control).
 
@@ -109,7 +109,6 @@
    To prevent that, we only call BLOCK/UNBLOCK from the main thread.  */
 
 static pthread_mutex_t alloc_mutex;
-pthread_t main_thread;
 
 #define BLOCK_INPUT_ALLOC                       \
   do                                            \
@@ -1310,8 +1309,6 @@
   pthread_mutexattr_init (&attr);
   pthread_mutexattr_settype (&attr, PTHREAD_MUTEX_RECURSIVE);
   pthread_mutex_init (&alloc_mutex, &attr);
-
-  main_thread = pthread_self ();
 #endif /* HAVE_GTK_AND_PTHREAD */
 
   if (__free_hook != emacs_blocked_free)
--- a/src/atimer.c	Wed Dec 15 21:34:14 2004 +0000
+++ b/src/atimer.c	Wed Dec 15 21:40:41 2004 +0000
@@ -364,6 +364,8 @@
 {
   EMACS_TIME now;
 
+  SIGNAL_THREAD_CHECK (signo);
+
   EMACS_GET_TIME (now);
   pending_atimers = 0;
 
--- a/src/data.c	Wed Dec 15 21:34:14 2004 +0000
+++ b/src/data.c	Wed Dec 15 21:40:41 2004 +0000
@@ -3366,6 +3366,7 @@
   sigsetmask (SIGEMPTYMASK);
 #endif /* not BSD4_1 */
 
+  SIGNAL_THREAD_CHECK (signo);
   Fsignal (Qarith_error, Qnil);
 }
 
--- a/src/dispnew.c	Wed Dec 15 21:34:14 2004 +0000
+++ b/src/dispnew.c	Wed Dec 15 21:40:41 2004 +0000
@@ -5994,6 +5994,9 @@
 #endif
   int old_errno = errno;
 
+  signal (SIGWINCH, window_change_signal);
+  SIGNAL_THREAD_CHECK (signalnum);
+
   get_frame_size (&width, &height);
 
   /* The frame size change obviously applies to a termcap-controlled
@@ -6016,7 +6019,6 @@
       }
   }
 
-  signal (SIGWINCH, window_change_signal);
   errno = old_errno;
 }
 #endif /* SIGWINCH */
--- a/src/emacs.c	Wed Dec 15 21:34:14 2004 +0000
+++ b/src/emacs.c	Wed Dec 15 21:40:41 2004 +0000
@@ -342,6 +342,14 @@
 
 void (*fatal_error_signal_hook) P_ ((void));
 
+#ifdef HAVE_GTK_AND_PTHREAD
+/* When compiled with GTK and running under Gnome, multiple threads meay be
+   created.  Keep track of our main thread to make sure signals are delivered
+   to it (see syssignal.h).  */
+
+pthread_t main_thread;
+#endif
+
 
 #ifdef SIGUSR1
 SIGTYPE
@@ -350,6 +358,7 @@
 {
   struct input_event buf;
 
+  SIGNAL_THREAD_CHECK (sig);
   bzero (&buf, sizeof buf);
   buf.kind = USER_SIGNAL_EVENT;
   buf.frame_or_window = selected_frame;
@@ -365,6 +374,7 @@
 {
   struct input_event buf;
 
+  SIGNAL_THREAD_CHECK (sig);
   bzero (&buf, sizeof buf);
   buf.kind = USER_SIGNAL_EVENT;
   buf.code = 1;
@@ -379,6 +389,7 @@
 fatal_error_signal (sig)
      int sig;
 {
+  SIGNAL_THREAD_CHECK (sig);
   fatal_error_code = sig;
   signal (sig, SIG_DFL);
 
@@ -418,6 +429,7 @@
      int sig;
 {
   signal (sig, memory_warning_signal);
+  SIGNAL_THREAD_CHECK (sig);
 
   malloc_warning ("Operating system warns that virtual memory is running low.\n");
 
@@ -1029,6 +1041,10 @@
 # endif /* not SYNC_INPUT */
 #endif	/* not SYSTEM_MALLOC */
 
+#ifdef HAVE_GTK_AND_PTHREAD
+  main_thread = pthread_self ();
+#endif /* HAVE_GTK_AND_PTHREAD */
+
 #if defined (MSDOS) || defined (WINDOWSNT)
   /* We do all file input/output as binary files.  When we need to translate
      newlines, we do that manually.  */
--- a/src/floatfns.c	Wed Dec 15 21:34:14 2004 +0000
+++ b/src/floatfns.c	Wed Dec 15 21:40:41 2004 +0000
@@ -981,6 +981,7 @@
   signal (SIGILL, float_error);
 #endif /* BSD_SYSTEM */
 
+  SIGNAL_THREAD_CHECK (signo);
   in_float = 0;
 
   Fsignal (Qarith_error, Fcons (float_error_arg, Qnil));
--- a/src/keyboard.c	Wed Dec 15 21:34:14 2004 +0000
+++ b/src/keyboard.c	Wed Dec 15 21:40:41 2004 +0000
@@ -6838,23 +6838,7 @@
   interrupt_input_pending = 1;
 #else
 
-# if !defined (SYSTEM_MALLOC) && defined (HAVE_GTK_AND_PTHREAD)
-  extern pthread_t main_thread;
-  if (pthread_self () != main_thread)
-    {
-      /* POSIX says any thread can receive the signal.  On GNU/Linux that is
-         not true, but for other systems (FreeBSD at least) it is.  So direct
-         the signal to the correct thread and block it from this thread.  */
-      sigset_t new_mask;
-
-      sigemptyset (&new_mask);
-      sigaddset (&new_mask, SIGIO);
-      pthread_sigmask (SIG_BLOCK, &new_mask, 0);
-      pthread_kill (main_thread, SIGIO);
-      return;
-    }
-# endif /* HAVE_GTK_AND_PTHREAD */
-
+  SIGNAL_THREAD_CHECK (signo);
   handle_async_input ();
 #endif
 
@@ -10270,6 +10254,7 @@
     }
 #endif /* USG */
 
+  SIGNAL_THREAD_CHECK (signalnum);
   cancel_echoing ();
 
   if (!NILP (Vquit_flag)
--- a/src/process.c	Wed Dec 15 21:34:14 2004 +0000
+++ b/src/process.c	Wed Dec 15 21:40:41 2004 +0000
@@ -5104,6 +5104,7 @@
 SIGTYPE
 send_process_trap ()
 {
+  SIGNAL_THREAD_CHECK (SIGPIPE);
 #ifdef BSD4_1
   sigrelse (SIGPIPE);
   sigrelse (SIGALRM);
@@ -6146,6 +6147,8 @@
   register struct Lisp_Process *p;
   extern EMACS_TIME *input_available_clear_time;
 
+  SIGNAL_THREAD_CHECK (signo);
+
 #ifdef BSD4_1
   extern int sigheld;
   sigheld |= sigbit (SIGCHLD);
--- a/src/sysdep.c	Wed Dec 15 21:34:14 2004 +0000
+++ b/src/sysdep.c	Wed Dec 15 21:40:41 2004 +0000
@@ -2472,6 +2472,7 @@
 #else /* not BSD4_1 */
   signal (SIGALRM, SIG_IGN);
 #endif /* not BSD4_1 */
+  SIGNAL_THREAD_CHECK (SIGALRM);
   if (read_alarm_should_throw)
     longjmp (read_alarm_throw, 1);
 }
--- a/src/syssignal.h	Wed Dec 15 21:34:14 2004 +0000
+++ b/src/syssignal.h	Wed Dec 15 21:40:41 2004 +0000
@@ -20,6 +20,11 @@
 
 extern void init_signals P_ ((void));
 
+#ifdef HAVE_GTK_AND_PTHREAD
+#include <pthread.h>
+extern pthread_t main_thread;
+#endif
+
 #ifdef POSIX_SIGNALS
 
 /* Don't #include <signal.h>.  That header should always be #included
@@ -198,5 +203,27 @@
 char *strsignal ();
 #endif
 
+#ifdef HAVE_GTK_AND_PTHREAD
+#define SIGNAL_THREAD_CHECK(signo)                                      \
+  do {                                                                  \
+    if (pthread_self () != main_thread)                                 \
+      {                                                                 \
+        /* POSIX says any thread can receive the signal.  On GNU/Linux  \
+           that is not true, but for other systems (FreeBSD at least)   \
+           it is.  So direct the signal to the correct thread and block \
+           it from this thread.  */                                     \
+        sigset_t new_mask;                                              \
+                                                                        \
+        sigemptyset (&new_mask);                                        \
+        sigaddset (&new_mask, signo);                                   \
+        pthread_sigmask (SIG_BLOCK, &new_mask, 0);                      \
+        pthread_kill (main_thread, signo);                              \
+        return;                                                         \
+      }                                                                 \
+   } while (0)
+
+#else /* not HAVE_GTK_AND_PTHREAD */
+#define SIGNAL_THREAD_CHECK(signo)
+#endif /* not HAVE_GTK_AND_PTHREAD */
 /* arch-tag: 4580e86a-340d-4574-9e11-a742b6e1a152
    (do not change this comment) */