Commit 333f1b6f authored by Jan Djärv's avatar Jan Djärv

* 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.
parent fecad3f6
2004-12-15 Jan Dj,Ad(Brv <jan.h.d@swipnet.se> 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 * xterm.c (xg_scroll_callback): Update XG_LAST_SB_DATA before
returning when xg_ignore_gtk_scrollbar is true. returning when xg_ignore_gtk_scrollbar is true.
......
...@@ -99,7 +99,7 @@ extern __malloc_size_t __malloc_extra_blocks; ...@@ -99,7 +99,7 @@ extern __malloc_size_t __malloc_extra_blocks;
If Emacs sets malloc hooks (! SYSTEM_MALLOC) and the emacs_blocked_* If Emacs sets malloc hooks (! SYSTEM_MALLOC) and the emacs_blocked_*
functions below are called from malloc, there is a chance that one functions below are called from malloc, there is a chance that one
of these threads preempts the Emacs main thread and the hook variables 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 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). but Emacs code running in the main thread is not included in that control).
...@@ -109,7 +109,6 @@ extern __malloc_size_t __malloc_extra_blocks; ...@@ -109,7 +109,6 @@ extern __malloc_size_t __malloc_extra_blocks;
To prevent that, we only call BLOCK/UNBLOCK from the main thread. */ To prevent that, we only call BLOCK/UNBLOCK from the main thread. */
static pthread_mutex_t alloc_mutex; static pthread_mutex_t alloc_mutex;
pthread_t main_thread;
#define BLOCK_INPUT_ALLOC \ #define BLOCK_INPUT_ALLOC \
do \ do \
...@@ -1310,8 +1309,6 @@ uninterrupt_malloc () ...@@ -1310,8 +1309,6 @@ uninterrupt_malloc ()
pthread_mutexattr_init (&attr); pthread_mutexattr_init (&attr);
pthread_mutexattr_settype (&attr, PTHREAD_MUTEX_RECURSIVE); pthread_mutexattr_settype (&attr, PTHREAD_MUTEX_RECURSIVE);
pthread_mutex_init (&alloc_mutex, &attr); pthread_mutex_init (&alloc_mutex, &attr);
main_thread = pthread_self ();
#endif /* HAVE_GTK_AND_PTHREAD */ #endif /* HAVE_GTK_AND_PTHREAD */
if (__free_hook != emacs_blocked_free) if (__free_hook != emacs_blocked_free)
......
...@@ -364,6 +364,8 @@ alarm_signal_handler (signo) ...@@ -364,6 +364,8 @@ alarm_signal_handler (signo)
{ {
EMACS_TIME now; EMACS_TIME now;
SIGNAL_THREAD_CHECK (signo);
EMACS_GET_TIME (now); EMACS_GET_TIME (now);
pending_atimers = 0; pending_atimers = 0;
......
...@@ -3366,6 +3366,7 @@ arith_error (signo) ...@@ -3366,6 +3366,7 @@ arith_error (signo)
sigsetmask (SIGEMPTYMASK); sigsetmask (SIGEMPTYMASK);
#endif /* not BSD4_1 */ #endif /* not BSD4_1 */
SIGNAL_THREAD_CHECK (signo);
Fsignal (Qarith_error, Qnil); Fsignal (Qarith_error, Qnil);
} }
......
...@@ -5994,6 +5994,9 @@ window_change_signal (signalnum) /* If we don't have an argument, */ ...@@ -5994,6 +5994,9 @@ window_change_signal (signalnum) /* If we don't have an argument, */
#endif #endif
int old_errno = errno; int old_errno = errno;
signal (SIGWINCH, window_change_signal);
SIGNAL_THREAD_CHECK (signalnum);
get_frame_size (&width, &height); get_frame_size (&width, &height);
/* The frame size change obviously applies to a termcap-controlled /* The frame size change obviously applies to a termcap-controlled
...@@ -6016,7 +6019,6 @@ window_change_signal (signalnum) /* If we don't have an argument, */ ...@@ -6016,7 +6019,6 @@ window_change_signal (signalnum) /* If we don't have an argument, */
} }
} }
signal (SIGWINCH, window_change_signal);
errno = old_errno; errno = old_errno;
} }
#endif /* SIGWINCH */ #endif /* SIGWINCH */
......
...@@ -342,6 +342,14 @@ int fatal_error_in_progress; ...@@ -342,6 +342,14 @@ int fatal_error_in_progress;
void (*fatal_error_signal_hook) P_ ((void)); 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 #ifdef SIGUSR1
SIGTYPE SIGTYPE
...@@ -350,6 +358,7 @@ handle_USR1_signal (sig) ...@@ -350,6 +358,7 @@ handle_USR1_signal (sig)
{ {
struct input_event buf; struct input_event buf;
SIGNAL_THREAD_CHECK (sig);
bzero (&buf, sizeof buf); bzero (&buf, sizeof buf);
buf.kind = USER_SIGNAL_EVENT; buf.kind = USER_SIGNAL_EVENT;
buf.frame_or_window = selected_frame; buf.frame_or_window = selected_frame;
...@@ -365,6 +374,7 @@ handle_USR2_signal (sig) ...@@ -365,6 +374,7 @@ handle_USR2_signal (sig)
{ {
struct input_event buf; struct input_event buf;
SIGNAL_THREAD_CHECK (sig);
bzero (&buf, sizeof buf); bzero (&buf, sizeof buf);
buf.kind = USER_SIGNAL_EVENT; buf.kind = USER_SIGNAL_EVENT;
buf.code = 1; buf.code = 1;
...@@ -379,6 +389,7 @@ SIGTYPE ...@@ -379,6 +389,7 @@ SIGTYPE
fatal_error_signal (sig) fatal_error_signal (sig)
int sig; int sig;
{ {
SIGNAL_THREAD_CHECK (sig);
fatal_error_code = sig; fatal_error_code = sig;
signal (sig, SIG_DFL); signal (sig, SIG_DFL);
...@@ -418,6 +429,7 @@ memory_warning_signal (sig) ...@@ -418,6 +429,7 @@ memory_warning_signal (sig)
int sig; int sig;
{ {
signal (sig, memory_warning_signal); signal (sig, memory_warning_signal);
SIGNAL_THREAD_CHECK (sig);
malloc_warning ("Operating system warns that virtual memory is running low.\n"); malloc_warning ("Operating system warns that virtual memory is running low.\n");
...@@ -1029,6 +1041,10 @@ main (argc, argv ...@@ -1029,6 +1041,10 @@ main (argc, argv
# endif /* not SYNC_INPUT */ # endif /* not SYNC_INPUT */
#endif /* not SYSTEM_MALLOC */ #endif /* not SYSTEM_MALLOC */
#ifdef HAVE_GTK_AND_PTHREAD
main_thread = pthread_self ();
#endif /* HAVE_GTK_AND_PTHREAD */
#if defined (MSDOS) || defined (WINDOWSNT) #if defined (MSDOS) || defined (WINDOWSNT)
/* We do all file input/output as binary files. When we need to translate /* We do all file input/output as binary files. When we need to translate
newlines, we do that manually. */ newlines, we do that manually. */
......
...@@ -981,6 +981,7 @@ float_error (signo) ...@@ -981,6 +981,7 @@ float_error (signo)
signal (SIGILL, float_error); signal (SIGILL, float_error);
#endif /* BSD_SYSTEM */ #endif /* BSD_SYSTEM */
SIGNAL_THREAD_CHECK (signo);
in_float = 0; in_float = 0;
Fsignal (Qarith_error, Fcons (float_error_arg, Qnil)); Fsignal (Qarith_error, Fcons (float_error_arg, Qnil));
......
...@@ -6838,23 +6838,7 @@ input_available_signal (signo) ...@@ -6838,23 +6838,7 @@ input_available_signal (signo)
interrupt_input_pending = 1; interrupt_input_pending = 1;
#else #else
# if !defined (SYSTEM_MALLOC) && defined (HAVE_GTK_AND_PTHREAD) SIGNAL_THREAD_CHECK (signo);
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 */
handle_async_input (); handle_async_input ();
#endif #endif
...@@ -10270,6 +10254,7 @@ interrupt_signal (signalnum) /* If we don't have an argument, */ ...@@ -10270,6 +10254,7 @@ interrupt_signal (signalnum) /* If we don't have an argument, */
} }
#endif /* USG */ #endif /* USG */
SIGNAL_THREAD_CHECK (signalnum);
cancel_echoing (); cancel_echoing ();
if (!NILP (Vquit_flag) if (!NILP (Vquit_flag)
......
...@@ -5104,6 +5104,7 @@ Lisp_Object process_sent_to; ...@@ -5104,6 +5104,7 @@ Lisp_Object process_sent_to;
SIGTYPE SIGTYPE
send_process_trap () send_process_trap ()
{ {
SIGNAL_THREAD_CHECK (SIGPIPE);
#ifdef BSD4_1 #ifdef BSD4_1
sigrelse (SIGPIPE); sigrelse (SIGPIPE);
sigrelse (SIGALRM); sigrelse (SIGALRM);
...@@ -6146,6 +6147,8 @@ sigchld_handler (signo) ...@@ -6146,6 +6147,8 @@ sigchld_handler (signo)
register struct Lisp_Process *p; register struct Lisp_Process *p;
extern EMACS_TIME *input_available_clear_time; extern EMACS_TIME *input_available_clear_time;
SIGNAL_THREAD_CHECK (signo);
#ifdef BSD4_1 #ifdef BSD4_1
extern int sigheld; extern int sigheld;
sigheld |= sigbit (SIGCHLD); sigheld |= sigbit (SIGCHLD);
......
...@@ -2472,6 +2472,7 @@ select_alarm () ...@@ -2472,6 +2472,7 @@ select_alarm ()
#else /* not BSD4_1 */ #else /* not BSD4_1 */
signal (SIGALRM, SIG_IGN); signal (SIGALRM, SIG_IGN);
#endif /* not BSD4_1 */ #endif /* not BSD4_1 */
SIGNAL_THREAD_CHECK (SIGALRM);
if (read_alarm_should_throw) if (read_alarm_should_throw)
longjmp (read_alarm_throw, 1); longjmp (read_alarm_throw, 1);
} }
......
...@@ -20,6 +20,11 @@ Boston, MA 02111-1307, USA. */ ...@@ -20,6 +20,11 @@ Boston, MA 02111-1307, USA. */
extern void init_signals P_ ((void)); extern void init_signals P_ ((void));
#ifdef HAVE_GTK_AND_PTHREAD
#include <pthread.h>
extern pthread_t main_thread;
#endif
#ifdef POSIX_SIGNALS #ifdef POSIX_SIGNALS
/* Don't #include <signal.h>. That header should always be #included /* Don't #include <signal.h>. That header should always be #included
...@@ -198,5 +203,27 @@ extern SIGMASKTYPE sigprocmask_set; ...@@ -198,5 +203,27 @@ extern SIGMASKTYPE sigprocmask_set;
char *strsignal (); char *strsignal ();
#endif #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 /* arch-tag: 4580e86a-340d-4574-9e11-a742b6e1a152
(do not change this comment) */ (do not change this comment) */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment