mirror of
https://git.savannah.gnu.org/git/emacs.git
synced 2025-02-08 20:58:58 +00:00
* 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.
This commit is contained in:
parent
fecad3f659
commit
333f1b6f78
@ -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.
|
||||
|
||||
|
@ -99,7 +99,7 @@ extern __malloc_size_t __malloc_extra_blocks;
|
||||
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 @@ extern __malloc_size_t __malloc_extra_blocks;
|
||||
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 @@ uninterrupt_malloc ()
|
||||
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)
|
||||
|
@ -364,6 +364,8 @@ alarm_signal_handler (signo)
|
||||
{
|
||||
EMACS_TIME now;
|
||||
|
||||
SIGNAL_THREAD_CHECK (signo);
|
||||
|
||||
EMACS_GET_TIME (now);
|
||||
pending_atimers = 0;
|
||||
|
||||
|
@ -3366,6 +3366,7 @@ arith_error (signo)
|
||||
sigsetmask (SIGEMPTYMASK);
|
||||
#endif /* not BSD4_1 */
|
||||
|
||||
SIGNAL_THREAD_CHECK (signo);
|
||||
Fsignal (Qarith_error, Qnil);
|
||||
}
|
||||
|
||||
|
@ -5994,6 +5994,9 @@ window_change_signal (signalnum) /* If we don't have an argument, */
|
||||
#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 @@ window_change_signal (signalnum) /* If we don't have an argument, */
|
||||
}
|
||||
}
|
||||
|
||||
signal (SIGWINCH, window_change_signal);
|
||||
errno = old_errno;
|
||||
}
|
||||
#endif /* SIGWINCH */
|
||||
|
16
src/emacs.c
16
src/emacs.c
@ -342,6 +342,14 @@ int fatal_error_in_progress;
|
||||
|
||||
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 @@ handle_USR1_signal (sig)
|
||||
{
|
||||
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 @@ handle_USR2_signal (sig)
|
||||
{
|
||||
struct input_event buf;
|
||||
|
||||
SIGNAL_THREAD_CHECK (sig);
|
||||
bzero (&buf, sizeof buf);
|
||||
buf.kind = USER_SIGNAL_EVENT;
|
||||
buf.code = 1;
|
||||
@ -379,6 +389,7 @@ SIGTYPE
|
||||
fatal_error_signal (sig)
|
||||
int sig;
|
||||
{
|
||||
SIGNAL_THREAD_CHECK (sig);
|
||||
fatal_error_code = sig;
|
||||
signal (sig, SIG_DFL);
|
||||
|
||||
@ -418,6 +429,7 @@ memory_warning_signal (sig)
|
||||
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 @@ main (argc, argv
|
||||
# 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. */
|
||||
|
@ -981,6 +981,7 @@ float_error (signo)
|
||||
signal (SIGILL, float_error);
|
||||
#endif /* BSD_SYSTEM */
|
||||
|
||||
SIGNAL_THREAD_CHECK (signo);
|
||||
in_float = 0;
|
||||
|
||||
Fsignal (Qarith_error, Fcons (float_error_arg, Qnil));
|
||||
|
@ -6838,23 +6838,7 @@ input_available_signal (signo)
|
||||
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 @@ interrupt_signal (signalnum) /* If we don't have an argument, */
|
||||
}
|
||||
#endif /* USG */
|
||||
|
||||
SIGNAL_THREAD_CHECK (signalnum);
|
||||
cancel_echoing ();
|
||||
|
||||
if (!NILP (Vquit_flag)
|
||||
|
@ -5104,6 +5104,7 @@ Lisp_Object process_sent_to;
|
||||
SIGTYPE
|
||||
send_process_trap ()
|
||||
{
|
||||
SIGNAL_THREAD_CHECK (SIGPIPE);
|
||||
#ifdef BSD4_1
|
||||
sigrelse (SIGPIPE);
|
||||
sigrelse (SIGALRM);
|
||||
@ -6146,6 +6147,8 @@ sigchld_handler (signo)
|
||||
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);
|
||||
|
@ -2472,6 +2472,7 @@ select_alarm ()
|
||||
#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);
|
||||
}
|
||||
|
@ -20,6 +20,11 @@ Boston, MA 02111-1307, USA. */
|
||||
|
||||
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 @@ extern SIGMASKTYPE sigprocmask_set;
|
||||
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) */
|
||||
|
Loading…
x
Reference in New Issue
Block a user