aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJan Djärv2004-12-15 21:40:41 +0000
committerJan Djärv2004-12-15 21:40:41 +0000
commit333f1b6f78ea3923fd49c8bb7f4d4aef39549591 (patch)
tree9f8044dff23e460bb11e8aa324cec148e1ca89b0 /src
parentfecad3f6597e12724d2329354905a99450347d0c (diff)
downloademacs-333f1b6f78ea3923fd49c8bb7f4d4aef39549591.tar.gz
emacs-333f1b6f78ea3923fd49c8bb7f4d4aef39549591.zip
* 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.
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog27
-rw-r--r--src/alloc.c5
-rw-r--r--src/atimer.c2
-rw-r--r--src/data.c1
-rw-r--r--src/dispnew.c4
-rw-r--r--src/emacs.c16
-rw-r--r--src/floatfns.c1
-rw-r--r--src/keyboard.c19
-rw-r--r--src/process.c3
-rw-r--r--src/sysdep.c1
-rw-r--r--src/syssignal.h27
11 files changed, 84 insertions, 22 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index abeef641313..63f0fe42a37 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,5 +1,32 @@
12004-12-15 Jan Dj,Ad(Brv <jan.h.d@swipnet.se> 12004-12-15 Jan Dj,Ad(Brv <jan.h.d@swipnet.se>
2 2
3 * syssignal.h: Declare main_thread.
4 (SIGNAL_THREAD_CHECK): New macro.
5
6 * keyboard.c (input_available_signal): Move thread checking code
7 to macro SIGNAL_THREAD_CHECK and call that macro.
8 (interrupt_signal): Call SIGNAL_THREAD_CHECK.
9
10 * alloc.c (uninterrupt_malloc): Move main_thread to emacs.c.
11
12 * emacs.c: Define main_thread.
13 (main): Initialize main_thread.
14 (handle_USR1_signal, handle_USR2_signal, fatal_error_signal)
15 (memory_warning_signal): Call SIGNAL_THREAD_CHECK.
16
17 * floatfns.c (float_error): Call SIGNAL_THREAD_CHECK.
18
19 * dispnew.c (window_change_signal): Call SIGNAL_THREAD_CHECK.
20
21 * sysdep.c (select_alarm): Call SIGNAL_THREAD_CHECK.
22
23 * process.c (send_process_trap, sigchld_handler): Call
24 SIGNAL_THREAD_CHECK.
25
26 * data.c (arith_error): Call SIGNAL_THREAD_CHECK.
27
28 * atimer.c (alarm_signal_handler): Call SIGNAL_THREAD_CHECK.
29
3 * xterm.c (xg_scroll_callback): Update XG_LAST_SB_DATA before 30 * xterm.c (xg_scroll_callback): Update XG_LAST_SB_DATA before
4 returning when xg_ignore_gtk_scrollbar is true. 31 returning when xg_ignore_gtk_scrollbar is true.
5 32
diff --git a/src/alloc.c b/src/alloc.c
index 0ea389117ba..5038fdfce10 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -99,7 +99,7 @@ extern __malloc_size_t __malloc_extra_blocks;
99 If Emacs sets malloc hooks (! SYSTEM_MALLOC) and the emacs_blocked_* 99 If Emacs sets malloc hooks (! SYSTEM_MALLOC) and the emacs_blocked_*
100 functions below are called from malloc, there is a chance that one 100 functions below are called from malloc, there is a chance that one
101 of these threads preempts the Emacs main thread and the hook variables 101 of these threads preempts the Emacs main thread and the hook variables
102 end up in a inconsistent state. So we have a mutex to prevent that (note 102 end up in an inconsistent state. So we have a mutex to prevent that (note
103 that the backend handles concurrent access to malloc within its own threads 103 that the backend handles concurrent access to malloc within its own threads
104 but Emacs code running in the main thread is not included in that control). 104 but Emacs code running in the main thread is not included in that control).
105 105
@@ -109,7 +109,6 @@ extern __malloc_size_t __malloc_extra_blocks;
109 To prevent that, we only call BLOCK/UNBLOCK from the main thread. */ 109 To prevent that, we only call BLOCK/UNBLOCK from the main thread. */
110 110
111static pthread_mutex_t alloc_mutex; 111static pthread_mutex_t alloc_mutex;
112pthread_t main_thread;
113 112
114#define BLOCK_INPUT_ALLOC \ 113#define BLOCK_INPUT_ALLOC \
115 do \ 114 do \
@@ -1310,8 +1309,6 @@ uninterrupt_malloc ()
1310 pthread_mutexattr_init (&attr); 1309 pthread_mutexattr_init (&attr);
1311 pthread_mutexattr_settype (&attr, PTHREAD_MUTEX_RECURSIVE); 1310 pthread_mutexattr_settype (&attr, PTHREAD_MUTEX_RECURSIVE);
1312 pthread_mutex_init (&alloc_mutex, &attr); 1311 pthread_mutex_init (&alloc_mutex, &attr);
1313
1314 main_thread = pthread_self ();
1315#endif /* HAVE_GTK_AND_PTHREAD */ 1312#endif /* HAVE_GTK_AND_PTHREAD */
1316 1313
1317 if (__free_hook != emacs_blocked_free) 1314 if (__free_hook != emacs_blocked_free)
diff --git a/src/atimer.c b/src/atimer.c
index 7410cad0244..ff5b8faaf36 100644
--- a/src/atimer.c
+++ b/src/atimer.c
@@ -364,6 +364,8 @@ alarm_signal_handler (signo)
364{ 364{
365 EMACS_TIME now; 365 EMACS_TIME now;
366 366
367 SIGNAL_THREAD_CHECK (signo);
368
367 EMACS_GET_TIME (now); 369 EMACS_GET_TIME (now);
368 pending_atimers = 0; 370 pending_atimers = 0;
369 371
diff --git a/src/data.c b/src/data.c
index afbca80181d..811619b58b3 100644
--- a/src/data.c
+++ b/src/data.c
@@ -3366,6 +3366,7 @@ arith_error (signo)
3366 sigsetmask (SIGEMPTYMASK); 3366 sigsetmask (SIGEMPTYMASK);
3367#endif /* not BSD4_1 */ 3367#endif /* not BSD4_1 */
3368 3368
3369 SIGNAL_THREAD_CHECK (signo);
3369 Fsignal (Qarith_error, Qnil); 3370 Fsignal (Qarith_error, Qnil);
3370} 3371}
3371 3372
diff --git a/src/dispnew.c b/src/dispnew.c
index 69e495d8d8b..78ca0e39109 100644
--- a/src/dispnew.c
+++ b/src/dispnew.c
@@ -5994,6 +5994,9 @@ window_change_signal (signalnum) /* If we don't have an argument, */
5994#endif 5994#endif
5995 int old_errno = errno; 5995 int old_errno = errno;
5996 5996
5997 signal (SIGWINCH, window_change_signal);
5998 SIGNAL_THREAD_CHECK (signalnum);
5999
5997 get_frame_size (&width, &height); 6000 get_frame_size (&width, &height);
5998 6001
5999 /* The frame size change obviously applies to a termcap-controlled 6002 /* 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 } 6019 }
6017 } 6020 }
6018 6021
6019 signal (SIGWINCH, window_change_signal);
6020 errno = old_errno; 6022 errno = old_errno;
6021} 6023}
6022#endif /* SIGWINCH */ 6024#endif /* SIGWINCH */
diff --git a/src/emacs.c b/src/emacs.c
index 9fde3a6ed42..791e13dd6d0 100644
--- a/src/emacs.c
+++ b/src/emacs.c
@@ -342,6 +342,14 @@ int fatal_error_in_progress;
342 342
343void (*fatal_error_signal_hook) P_ ((void)); 343void (*fatal_error_signal_hook) P_ ((void));
344 344
345#ifdef HAVE_GTK_AND_PTHREAD
346/* When compiled with GTK and running under Gnome, multiple threads meay be
347 created. Keep track of our main thread to make sure signals are delivered
348 to it (see syssignal.h). */
349
350pthread_t main_thread;
351#endif
352
345 353
346#ifdef SIGUSR1 354#ifdef SIGUSR1
347SIGTYPE 355SIGTYPE
@@ -350,6 +358,7 @@ handle_USR1_signal (sig)
350{ 358{
351 struct input_event buf; 359 struct input_event buf;
352 360
361 SIGNAL_THREAD_CHECK (sig);
353 bzero (&buf, sizeof buf); 362 bzero (&buf, sizeof buf);
354 buf.kind = USER_SIGNAL_EVENT; 363 buf.kind = USER_SIGNAL_EVENT;
355 buf.frame_or_window = selected_frame; 364 buf.frame_or_window = selected_frame;
@@ -365,6 +374,7 @@ handle_USR2_signal (sig)
365{ 374{
366 struct input_event buf; 375 struct input_event buf;
367 376
377 SIGNAL_THREAD_CHECK (sig);
368 bzero (&buf, sizeof buf); 378 bzero (&buf, sizeof buf);
369 buf.kind = USER_SIGNAL_EVENT; 379 buf.kind = USER_SIGNAL_EVENT;
370 buf.code = 1; 380 buf.code = 1;
@@ -379,6 +389,7 @@ SIGTYPE
379fatal_error_signal (sig) 389fatal_error_signal (sig)
380 int sig; 390 int sig;
381{ 391{
392 SIGNAL_THREAD_CHECK (sig);
382 fatal_error_code = sig; 393 fatal_error_code = sig;
383 signal (sig, SIG_DFL); 394 signal (sig, SIG_DFL);
384 395
@@ -418,6 +429,7 @@ memory_warning_signal (sig)
418 int sig; 429 int sig;
419{ 430{
420 signal (sig, memory_warning_signal); 431 signal (sig, memory_warning_signal);
432 SIGNAL_THREAD_CHECK (sig);
421 433
422 malloc_warning ("Operating system warns that virtual memory is running low.\n"); 434 malloc_warning ("Operating system warns that virtual memory is running low.\n");
423 435
@@ -1029,6 +1041,10 @@ main (argc, argv
1029# endif /* not SYNC_INPUT */ 1041# endif /* not SYNC_INPUT */
1030#endif /* not SYSTEM_MALLOC */ 1042#endif /* not SYSTEM_MALLOC */
1031 1043
1044#ifdef HAVE_GTK_AND_PTHREAD
1045 main_thread = pthread_self ();
1046#endif /* HAVE_GTK_AND_PTHREAD */
1047
1032#if defined (MSDOS) || defined (WINDOWSNT) 1048#if defined (MSDOS) || defined (WINDOWSNT)
1033 /* We do all file input/output as binary files. When we need to translate 1049 /* We do all file input/output as binary files. When we need to translate
1034 newlines, we do that manually. */ 1050 newlines, we do that manually. */
diff --git a/src/floatfns.c b/src/floatfns.c
index 61879eabe39..8cd08106ef2 100644
--- a/src/floatfns.c
+++ b/src/floatfns.c
@@ -981,6 +981,7 @@ float_error (signo)
981 signal (SIGILL, float_error); 981 signal (SIGILL, float_error);
982#endif /* BSD_SYSTEM */ 982#endif /* BSD_SYSTEM */
983 983
984 SIGNAL_THREAD_CHECK (signo);
984 in_float = 0; 985 in_float = 0;
985 986
986 Fsignal (Qarith_error, Fcons (float_error_arg, Qnil)); 987 Fsignal (Qarith_error, Fcons (float_error_arg, Qnil));
diff --git a/src/keyboard.c b/src/keyboard.c
index 95de9c2c6ad..ffd36acb335 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -6838,23 +6838,7 @@ input_available_signal (signo)
6838 interrupt_input_pending = 1; 6838 interrupt_input_pending = 1;
6839#else 6839#else
6840 6840
6841# if !defined (SYSTEM_MALLOC) && defined (HAVE_GTK_AND_PTHREAD) 6841 SIGNAL_THREAD_CHECK (signo);
6842 extern pthread_t main_thread;
6843 if (pthread_self () != main_thread)
6844 {
6845 /* POSIX says any thread can receive the signal. On GNU/Linux that is
6846 not true, but for other systems (FreeBSD at least) it is. So direct
6847 the signal to the correct thread and block it from this thread. */
6848 sigset_t new_mask;
6849
6850 sigemptyset (&new_mask);
6851 sigaddset (&new_mask, SIGIO);
6852 pthread_sigmask (SIG_BLOCK, &new_mask, 0);
6853 pthread_kill (main_thread, SIGIO);
6854 return;
6855 }
6856# endif /* HAVE_GTK_AND_PTHREAD */
6857
6858 handle_async_input (); 6842 handle_async_input ();
6859#endif 6843#endif
6860 6844
@@ -10270,6 +10254,7 @@ interrupt_signal (signalnum) /* If we don't have an argument, */
10270 } 10254 }
10271#endif /* USG */ 10255#endif /* USG */
10272 10256
10257 SIGNAL_THREAD_CHECK (signalnum);
10273 cancel_echoing (); 10258 cancel_echoing ();
10274 10259
10275 if (!NILP (Vquit_flag) 10260 if (!NILP (Vquit_flag)
diff --git a/src/process.c b/src/process.c
index ec07e95c34a..ad4cf8f8546 100644
--- a/src/process.c
+++ b/src/process.c
@@ -5104,6 +5104,7 @@ Lisp_Object process_sent_to;
5104SIGTYPE 5104SIGTYPE
5105send_process_trap () 5105send_process_trap ()
5106{ 5106{
5107 SIGNAL_THREAD_CHECK (SIGPIPE);
5107#ifdef BSD4_1 5108#ifdef BSD4_1
5108 sigrelse (SIGPIPE); 5109 sigrelse (SIGPIPE);
5109 sigrelse (SIGALRM); 5110 sigrelse (SIGALRM);
@@ -6146,6 +6147,8 @@ sigchld_handler (signo)
6146 register struct Lisp_Process *p; 6147 register struct Lisp_Process *p;
6147 extern EMACS_TIME *input_available_clear_time; 6148 extern EMACS_TIME *input_available_clear_time;
6148 6149
6150 SIGNAL_THREAD_CHECK (signo);
6151
6149#ifdef BSD4_1 6152#ifdef BSD4_1
6150 extern int sigheld; 6153 extern int sigheld;
6151 sigheld |= sigbit (SIGCHLD); 6154 sigheld |= sigbit (SIGCHLD);
diff --git a/src/sysdep.c b/src/sysdep.c
index 6284774d092..1884c0ccffa 100644
--- a/src/sysdep.c
+++ b/src/sysdep.c
@@ -2472,6 +2472,7 @@ select_alarm ()
2472#else /* not BSD4_1 */ 2472#else /* not BSD4_1 */
2473 signal (SIGALRM, SIG_IGN); 2473 signal (SIGALRM, SIG_IGN);
2474#endif /* not BSD4_1 */ 2474#endif /* not BSD4_1 */
2475 SIGNAL_THREAD_CHECK (SIGALRM);
2475 if (read_alarm_should_throw) 2476 if (read_alarm_should_throw)
2476 longjmp (read_alarm_throw, 1); 2477 longjmp (read_alarm_throw, 1);
2477} 2478}
diff --git a/src/syssignal.h b/src/syssignal.h
index cef71f7459a..04e84df1a3a 100644
--- a/src/syssignal.h
+++ b/src/syssignal.h
@@ -20,6 +20,11 @@ Boston, MA 02111-1307, USA. */
20 20
21extern void init_signals P_ ((void)); 21extern void init_signals P_ ((void));
22 22
23#ifdef HAVE_GTK_AND_PTHREAD
24#include <pthread.h>
25extern pthread_t main_thread;
26#endif
27
23#ifdef POSIX_SIGNALS 28#ifdef POSIX_SIGNALS
24 29
25/* Don't #include <signal.h>. That header should always be #included 30/* Don't #include <signal.h>. That header should always be #included
@@ -198,5 +203,27 @@ extern SIGMASKTYPE sigprocmask_set;
198char *strsignal (); 203char *strsignal ();
199#endif 204#endif
200 205
206#ifdef HAVE_GTK_AND_PTHREAD
207#define SIGNAL_THREAD_CHECK(signo) \
208 do { \
209 if (pthread_self () != main_thread) \
210 { \
211 /* POSIX says any thread can receive the signal. On GNU/Linux \
212 that is not true, but for other systems (FreeBSD at least) \
213 it is. So direct the signal to the correct thread and block \
214 it from this thread. */ \
215 sigset_t new_mask; \
216 \
217 sigemptyset (&new_mask); \
218 sigaddset (&new_mask, signo); \
219 pthread_sigmask (SIG_BLOCK, &new_mask, 0); \
220 pthread_kill (main_thread, signo); \
221 return; \
222 } \
223 } while (0)
224
225#else /* not HAVE_GTK_AND_PTHREAD */
226#define SIGNAL_THREAD_CHECK(signo)
227#endif /* not HAVE_GTK_AND_PTHREAD */
201/* arch-tag: 4580e86a-340d-4574-9e11-a742b6e1a152 228/* arch-tag: 4580e86a-340d-4574-9e11-a742b6e1a152
202 (do not change this comment) */ 229 (do not change this comment) */