aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPaul Eggert2012-09-16 14:43:55 -0700
committerPaul Eggert2012-09-16 14:43:55 -0700
commit0caaedb1c3c9c48980144e41d2a95329d39c399a (patch)
tree3e191e2b290e9adf91594be047c1f268cacde932 /src
parent634b8cacd6cc0557c1963ad7409db247963046d2 (diff)
downloademacs-0caaedb1c3c9c48980144e41d2a95329d39c399a.tar.gz
emacs-0caaedb1c3c9c48980144e41d2a95329d39c399a.zip
Remove configure's --without-sync-input option.
When auditing signal-handling in preparation for cleaning it up, I found that SYNC_INPUT has race conditions and would be a real pain to fix. Since it's an undocumented and deprecated configure-time option, now seems like a good time to remove it. Also see <http://bugs.gnu.org/11080#16>. * configure.ac (SYNC_INPUT, BROKEN_SA_RESTART): Remove. * admin/CPP-DEFINES (BROKEN_SA_RESTART, SA_RESTART): Remove. * etc/TODO (Make SYNC_INPUT the default): Remove, as the code now behaves as if SYNC_INPUT is always true. * src/alloc.c (_bytes_used, __malloc_extra_blocks, _malloc_internal) (_free_internal) [!DOUG_LEA_MALLOC]: Remove decls. (alloc_mutex) [!SYSTEM_MALLOC && !SYNC_INPUT && HAVE_PTHREAD]: (malloc_hysteresis): (check_depth) [XMALLOC_OVERRUN_CHECK]: (MALLOC_BLOCK_INPUT, MALLOC_UNBLOCK_INPUT): (__malloc_hook, __realloc_hook, __free_hook, BYTES_USED) (dont_register_blocks, bytes_used_when_reconsidered) (bytes_used_when_full, emacs_blocked_free, emacs_blocked_malloc) (emacs_blocked_realloc, reset_malloc_hooks, uninterrupt_malloc): [!SYSTEM_MALLOC && !SYNC_INPUT]: Remove. All uses removed. (MALLOC_BLOCK_INPUT, MALLOC_UNBLOCK_INPUT): Use a different implementation, one that depends on whether the new macro XMALLOC_BLOCK_INPUT_CHECK is defined, not on whether SYNC_INPUT is defined. * src/atimer.c (run_timers, handle_alarm_signal): * src/keyboard.c (pending_signal, poll_for_input_1, poll_for_input) (handle_async_input, process_pending_signals) (handle_input_available_signal, init_keyboard): * src/nsterm.m (ns_read_socket): * src/process.c (wait_reading_process_output): * src/regex.c (immediate_quit, IMMEDIATE_QUIT_CHECK): * src/sysdep.c (emacs_sigaction_init) [SA_RESTART]: (emacs_write): * src/xterm.c (XTread_socket): Assume SYNC_INPUT. * src/conf_post.h (SA_RESTART) [IRIX6_5]: Do not #undef. * src/eval.c (handling_signal): Remove. All uses removed. * src/lisp.h (ELSE_PENDING_SIGNALS): Remove. All uses replaced with the SYNC_INPUT version. (reset_malloc_hooks, uninterrupt_malloc, handling_signal): Remove decls. * src/sysdep.c, src/syssignal.h (main_thread) [FORWARD_SIGNAL_TO_MAIN_THREAD]: Now static. Fixes: debbugs:12450
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog42
-rw-r--r--src/alloc.c424
-rw-r--r--src/atimer.c9
-rw-r--r--src/bytecode.c3
-rw-r--r--src/conf_post.h1
-rw-r--r--src/emacs.c12
-rw-r--r--src/eval.c16
-rw-r--r--src/intervals.c3
-rw-r--r--src/keyboard.c37
-rw-r--r--src/lisp.h13
-rw-r--r--src/nsmenu.m5
-rw-r--r--src/nsterm.m9
-rw-r--r--src/process.c2
-rw-r--r--src/regex.c6
-rw-r--r--src/sysdep.c18
-rw-r--r--src/syssignal.h4
-rw-r--r--src/xdisp.c6
-rw-r--r--src/xterm.c12
18 files changed, 97 insertions, 525 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index 32cd7b3e813..f21395d9632 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,5 +1,47 @@
12012-09-16 Paul Eggert <eggert@cs.ucla.edu> 12012-09-16 Paul Eggert <eggert@cs.ucla.edu>
2 2
3 Remove configure's --without-sync-input option (Bug#12450).
4 When auditing signal-handling in preparation for cleaning it up,
5 I found that SYNC_INPUT has race conditions and would be a real
6 pain to fix. Since it's an undocumented and deprecated
7 configure-time option, now seems like a good time to remove it.
8 Also see <http://bugs.gnu.org/11080#16>.
9 * alloc.c (_bytes_used, __malloc_extra_blocks, _malloc_internal)
10 (_free_internal) [!DOUG_LEA_MALLOC]: Remove decls.
11 (alloc_mutex) [!SYSTEM_MALLOC && !SYNC_INPUT && HAVE_PTHREAD]:
12 (malloc_hysteresis):
13 (check_depth) [XMALLOC_OVERRUN_CHECK]:
14 (MALLOC_BLOCK_INPUT, MALLOC_UNBLOCK_INPUT):
15 (__malloc_hook, __realloc_hook, __free_hook, BYTES_USED)
16 (dont_register_blocks, bytes_used_when_reconsidered)
17 (bytes_used_when_full, emacs_blocked_free, emacs_blocked_malloc)
18 (emacs_blocked_realloc, reset_malloc_hooks, uninterrupt_malloc):
19 [!SYSTEM_MALLOC && !SYNC_INPUT]:
20 Remove. All uses removed.
21 (MALLOC_BLOCK_INPUT, MALLOC_UNBLOCK_INPUT): Use a different
22 implementation, one that depends on whether the new macro
23 XMALLOC_BLOCK_INPUT_CHECK is defined, not on whether SYNC_INPUT
24 is defined.
25 * atimer.c (run_timers, handle_alarm_signal):
26 * keyboard.c (pending_signal, poll_for_input_1, poll_for_input)
27 (handle_async_input, process_pending_signals)
28 (handle_input_available_signal, init_keyboard):
29 * nsterm.m (ns_read_socket):
30 * process.c (wait_reading_process_output):
31 * regex.c (immediate_quit, IMMEDIATE_QUIT_CHECK):
32 * sysdep.c (emacs_sigaction_init) [SA_RESTART]:
33 (emacs_write):
34 * xterm.c (XTread_socket):
35 Assume SYNC_INPUT.
36 * conf_post.h (SA_RESTART) [IRIX6_5]: Do not #undef.
37 * eval.c (handling_signal): Remove. All uses removed.
38 * lisp.h (ELSE_PENDING_SIGNALS): Remove.
39 All uses replaced with the SYNC_INPUT version.
40 (reset_malloc_hooks, uninterrupt_malloc, handling_signal):
41 Remove decls.
42 * sysdep.c, syssignal.h (main_thread) [FORWARD_SIGNAL_TO_MAIN_THREAD]:
43 Now static.
44
3 * font.c (Ffont_shape_gstring): Remove unused local. 45 * font.c (Ffont_shape_gstring): Remove unused local.
4 46
52012-09-16 Glenn Morris <rgm@gnu.org> 472012-09-16 Glenn Morris <rgm@gnu.org>
diff --git a/src/alloc.c b/src/alloc.c
index 0bfbb0c88b1..fb7d35b5590 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -85,68 +85,8 @@ extern void *sbrk ();
85 85
86#define MMAP_MAX_AREAS 100000000 86#define MMAP_MAX_AREAS 100000000
87 87
88#else /* not DOUG_LEA_MALLOC */
89
90/* The following come from gmalloc.c. */
91
92extern size_t _bytes_used;
93extern size_t __malloc_extra_blocks;
94extern void *_malloc_internal (size_t);
95extern void _free_internal (void *);
96
97#endif /* not DOUG_LEA_MALLOC */ 88#endif /* not DOUG_LEA_MALLOC */
98 89
99#if ! defined SYSTEM_MALLOC && ! defined SYNC_INPUT
100#ifdef HAVE_PTHREAD
101
102# include "syssignal.h"
103
104/* When GTK uses the file chooser dialog, different backends can be loaded
105 dynamically. One such a backend is the Gnome VFS backend that gets loaded
106 if you run Gnome. That backend creates several threads and also allocates
107 memory with malloc.
108
109 Also, gconf and gsettings may create several threads.
110
111 If Emacs sets malloc hooks (! SYSTEM_MALLOC) and the emacs_blocked_*
112 functions below are called from malloc, there is a chance that one
113 of these threads preempts the Emacs main thread and the hook variables
114 end up in an inconsistent state. So we have a mutex to prevent that (note
115 that the backend handles concurrent access to malloc within its own threads
116 but Emacs code running in the main thread is not included in that control).
117
118 When UNBLOCK_INPUT is called, reinvoke_input_signal may be called. If this
119 happens in one of the backend threads we will have two threads that tries
120 to run Emacs code at once, and the code is not prepared for that.
121 To prevent that, we only call BLOCK/UNBLOCK from the main thread. */
122
123static pthread_mutex_t alloc_mutex;
124
125#define BLOCK_INPUT_ALLOC \
126 do \
127 { \
128 if (pthread_equal (pthread_self (), main_thread)) \
129 BLOCK_INPUT; \
130 pthread_mutex_lock (&alloc_mutex); \
131 } \
132 while (0)
133#define UNBLOCK_INPUT_ALLOC \
134 do \
135 { \
136 pthread_mutex_unlock (&alloc_mutex); \
137 if (pthread_equal (pthread_self (), main_thread)) \
138 UNBLOCK_INPUT; \
139 } \
140 while (0)
141
142#else /* ! defined HAVE_PTHREAD */
143
144#define BLOCK_INPUT_ALLOC BLOCK_INPUT
145#define UNBLOCK_INPUT_ALLOC UNBLOCK_INPUT
146
147#endif /* ! defined HAVE_PTHREAD */
148#endif /* ! defined SYSTEM_MALLOC && ! defined SYNC_INPUT */
149
150/* Mark, unmark, query mark bit of a Lisp string. S must be a pointer 90/* Mark, unmark, query mark bit of a Lisp string. S must be a pointer
151 to a struct Lisp_String. */ 91 to a struct Lisp_String. */
152 92
@@ -205,10 +145,6 @@ static char *spare_memory[7];
205 145
206#define SPARE_MEMORY (1 << 14) 146#define SPARE_MEMORY (1 << 14)
207 147
208/* Number of extra blocks malloc should get when it needs more core. */
209
210static int malloc_hysteresis;
211
212/* Initialize it to a nonzero value to force it into data space 148/* Initialize it to a nonzero value to force it into data space
213 (rather than bss space). That way unexec will remap it into text 149 (rather than bss space). That way unexec will remap it into text
214 space (pure), on some systems. We have not implemented the 150 space (pure), on some systems. We have not implemented the
@@ -413,12 +349,12 @@ static void mark_memory (void *, void *);
413static void mem_init (void); 349static void mem_init (void);
414static struct mem_node *mem_insert (void *, void *, enum mem_type); 350static struct mem_node *mem_insert (void *, void *, enum mem_type);
415static void mem_insert_fixup (struct mem_node *); 351static void mem_insert_fixup (struct mem_node *);
416#endif
417static void mem_rotate_left (struct mem_node *); 352static void mem_rotate_left (struct mem_node *);
418static void mem_rotate_right (struct mem_node *); 353static void mem_rotate_right (struct mem_node *);
419static void mem_delete (struct mem_node *); 354static void mem_delete (struct mem_node *);
420static void mem_delete_fixup (struct mem_node *); 355static void mem_delete_fixup (struct mem_node *);
421static inline struct mem_node *mem_find (void *); 356static inline struct mem_node *mem_find (void *);
357#endif
422 358
423 359
424#if GC_MARK_STACK == GC_MARK_STACK_CHECK_GCPROS 360#if GC_MARK_STACK == GC_MARK_STACK_CHECK_GCPROS
@@ -587,39 +523,17 @@ xmalloc_get_size (unsigned char *ptr)
587} 523}
588 524
589 525
590/* The call depth in overrun_check functions. For example, this might happen:
591 xmalloc()
592 overrun_check_malloc()
593 -> malloc -> (via hook)_-> emacs_blocked_malloc
594 -> overrun_check_malloc
595 call malloc (hooks are NULL, so real malloc is called).
596 malloc returns 10000.
597 add overhead, return 10016.
598 <- (back in overrun_check_malloc)
599 add overhead again, return 10032
600 xmalloc returns 10032.
601
602 (time passes).
603
604 xfree(10032)
605 overrun_check_free(10032)
606 decrease overhead
607 free(10016) <- crash, because 10000 is the original pointer. */
608
609static ptrdiff_t check_depth;
610
611/* Like malloc, but wraps allocated block with header and trailer. */ 526/* Like malloc, but wraps allocated block with header and trailer. */
612 527
613static void * 528static void *
614overrun_check_malloc (size_t size) 529overrun_check_malloc (size_t size)
615{ 530{
616 register unsigned char *val; 531 register unsigned char *val;
617 int overhead = ++check_depth == 1 ? XMALLOC_OVERRUN_CHECK_OVERHEAD : 0; 532 if (SIZE_MAX - XMALLOC_OVERRUN_CHECK_OVERHEAD < size)
618 if (SIZE_MAX - overhead < size)
619 emacs_abort (); 533 emacs_abort ();
620 534
621 val = malloc (size + overhead); 535 val = malloc (size + XMALLOC_OVERRUN_CHECK_OVERHEAD);
622 if (val && check_depth == 1) 536 if (val)
623 { 537 {
624 memcpy (val, xmalloc_overrun_check_header, XMALLOC_OVERRUN_CHECK_SIZE); 538 memcpy (val, xmalloc_overrun_check_header, XMALLOC_OVERRUN_CHECK_SIZE);
625 val += XMALLOC_OVERRUN_CHECK_SIZE + XMALLOC_OVERRUN_SIZE_SIZE; 539 val += XMALLOC_OVERRUN_CHECK_SIZE + XMALLOC_OVERRUN_SIZE_SIZE;
@@ -627,7 +541,6 @@ overrun_check_malloc (size_t size)
627 memcpy (val + size, xmalloc_overrun_check_trailer, 541 memcpy (val + size, xmalloc_overrun_check_trailer,
628 XMALLOC_OVERRUN_CHECK_SIZE); 542 XMALLOC_OVERRUN_CHECK_SIZE);
629 } 543 }
630 --check_depth;
631 return val; 544 return val;
632} 545}
633 546
@@ -639,12 +552,10 @@ static void *
639overrun_check_realloc (void *block, size_t size) 552overrun_check_realloc (void *block, size_t size)
640{ 553{
641 register unsigned char *val = (unsigned char *) block; 554 register unsigned char *val = (unsigned char *) block;
642 int overhead = ++check_depth == 1 ? XMALLOC_OVERRUN_CHECK_OVERHEAD : 0; 555 if (SIZE_MAX - XMALLOC_OVERRUN_CHECK_OVERHEAD < size)
643 if (SIZE_MAX - overhead < size)
644 emacs_abort (); 556 emacs_abort ();
645 557
646 if (val 558 if (val
647 && check_depth == 1
648 && memcmp (xmalloc_overrun_check_header, 559 && memcmp (xmalloc_overrun_check_header,
649 val - XMALLOC_OVERRUN_CHECK_SIZE - XMALLOC_OVERRUN_SIZE_SIZE, 560 val - XMALLOC_OVERRUN_CHECK_SIZE - XMALLOC_OVERRUN_SIZE_SIZE,
650 XMALLOC_OVERRUN_CHECK_SIZE) == 0) 561 XMALLOC_OVERRUN_CHECK_SIZE) == 0)
@@ -658,9 +569,9 @@ overrun_check_realloc (void *block, size_t size)
658 memset (val, 0, XMALLOC_OVERRUN_CHECK_SIZE + XMALLOC_OVERRUN_SIZE_SIZE); 569 memset (val, 0, XMALLOC_OVERRUN_CHECK_SIZE + XMALLOC_OVERRUN_SIZE_SIZE);
659 } 570 }
660 571
661 val = realloc (val, size + overhead); 572 val = realloc (val, size + XMALLOC_OVERRUN_CHECK_OVERHEAD);
662 573
663 if (val && check_depth == 1) 574 if (val)
664 { 575 {
665 memcpy (val, xmalloc_overrun_check_header, XMALLOC_OVERRUN_CHECK_SIZE); 576 memcpy (val, xmalloc_overrun_check_header, XMALLOC_OVERRUN_CHECK_SIZE);
666 val += XMALLOC_OVERRUN_CHECK_SIZE + XMALLOC_OVERRUN_SIZE_SIZE; 577 val += XMALLOC_OVERRUN_CHECK_SIZE + XMALLOC_OVERRUN_SIZE_SIZE;
@@ -668,7 +579,6 @@ overrun_check_realloc (void *block, size_t size)
668 memcpy (val + size, xmalloc_overrun_check_trailer, 579 memcpy (val + size, xmalloc_overrun_check_trailer,
669 XMALLOC_OVERRUN_CHECK_SIZE); 580 XMALLOC_OVERRUN_CHECK_SIZE);
670 } 581 }
671 --check_depth;
672 return val; 582 return val;
673} 583}
674 584
@@ -679,9 +589,7 @@ overrun_check_free (void *block)
679{ 589{
680 unsigned char *val = (unsigned char *) block; 590 unsigned char *val = (unsigned char *) block;
681 591
682 ++check_depth;
683 if (val 592 if (val
684 && check_depth == 1
685 && memcmp (xmalloc_overrun_check_header, 593 && memcmp (xmalloc_overrun_check_header,
686 val - XMALLOC_OVERRUN_CHECK_SIZE - XMALLOC_OVERRUN_SIZE_SIZE, 594 val - XMALLOC_OVERRUN_CHECK_SIZE - XMALLOC_OVERRUN_SIZE_SIZE,
687 XMALLOC_OVERRUN_CHECK_SIZE) == 0) 595 XMALLOC_OVERRUN_CHECK_SIZE) == 0)
@@ -701,7 +609,6 @@ overrun_check_free (void *block)
701 } 609 }
702 610
703 free (val); 611 free (val);
704 --check_depth;
705} 612}
706 613
707#undef malloc 614#undef malloc
@@ -712,14 +619,33 @@ overrun_check_free (void *block)
712#define free overrun_check_free 619#define free overrun_check_free
713#endif 620#endif
714 621
715#ifdef SYNC_INPUT 622/* If compiled with XMALLOC_BLOCK_INPUT_CHECK, define a symbol
716/* When using SYNC_INPUT, we don't call malloc from a signal handler, so 623 BLOCK_INPUT_IN_MEMORY_ALLOCATORS that is visible to the debugger.
717 there's no need to block input around malloc. */ 624 If that variable is set, block input while in one of Emacs's memory
718#define MALLOC_BLOCK_INPUT ((void)0) 625 allocation functions. There should be no need for this debugging
719#define MALLOC_UNBLOCK_INPUT ((void)0) 626 option, since signal handlers do not allocate memory, but Emacs
627 formerly allocated memory in signal handlers and this compile-time
628 option remains as a way to help debug the issue should it rear its
629 ugly head again. */
630#ifdef XMALLOC_BLOCK_INPUT_CHECK
631bool block_input_in_memory_allocators EXTERNALLY_VISIBLE;
632static void
633malloc_block_input (void)
634{
635 if (block_input_in_memory_allocators)
636 BLOCK_INPUT;
637}
638static void
639malloc_unblock_input (void)
640{
641 if (block_input_in_memory_allocators)
642 UNBLOCK_INPUT;
643}
644# define MALLOC_BLOCK_INPUT malloc_block_input ()
645# define MALLOC_UNBLOCK_INPUT malloc_unblock_input ()
720#else 646#else
721#define MALLOC_BLOCK_INPUT BLOCK_INPUT 647# define MALLOC_BLOCK_INPUT ((void) 0)
722#define MALLOC_UNBLOCK_INPUT UNBLOCK_INPUT 648# define MALLOC_UNBLOCK_INPUT ((void) 0)
723#endif 649#endif
724 650
725/* Like malloc but check for no memory and block interrupt input.. */ 651/* Like malloc but check for no memory and block interrupt input.. */
@@ -788,8 +714,7 @@ xfree (void *block)
788 free (block); 714 free (block);
789 MALLOC_UNBLOCK_INPUT; 715 MALLOC_UNBLOCK_INPUT;
790 /* We don't call refill_memory_reserve here 716 /* We don't call refill_memory_reserve here
791 because that duplicates doing so in emacs_blocked_free 717 because in practice the call in r_alloc_free seems to suffice. */
792 and the criterion should go there. */
793} 718}
794 719
795 720
@@ -1216,256 +1141,6 @@ lisp_align_free (void *block)
1216} 1141}
1217 1142
1218 1143
1219#ifndef SYSTEM_MALLOC
1220
1221/* Arranging to disable input signals while we're in malloc.
1222
1223 This only works with GNU malloc. To help out systems which can't
1224 use GNU malloc, all the calls to malloc, realloc, and free
1225 elsewhere in the code should be inside a BLOCK_INPUT/UNBLOCK_INPUT
1226 pair; unfortunately, we have no idea what C library functions
1227 might call malloc, so we can't really protect them unless you're
1228 using GNU malloc. Fortunately, most of the major operating systems
1229 can use GNU malloc. */
1230
1231#ifndef SYNC_INPUT
1232/* When using SYNC_INPUT, we don't call malloc from a signal handler, so
1233 there's no need to block input around malloc. */
1234
1235#ifndef DOUG_LEA_MALLOC
1236extern void * (*__malloc_hook) (size_t, const void *);
1237extern void * (*__realloc_hook) (void *, size_t, const void *);
1238extern void (*__free_hook) (void *, const void *);
1239/* Else declared in malloc.h, perhaps with an extra arg. */
1240#endif /* DOUG_LEA_MALLOC */
1241static void * (*old_malloc_hook) (size_t, const void *);
1242static void * (*old_realloc_hook) (void *, size_t, const void*);
1243static void (*old_free_hook) (void*, const void*);
1244
1245#ifdef DOUG_LEA_MALLOC
1246# define BYTES_USED (mallinfo ().uordblks)
1247#else
1248# define BYTES_USED _bytes_used
1249#endif
1250
1251#ifdef GC_MALLOC_CHECK
1252static bool dont_register_blocks;
1253#endif
1254
1255static size_t bytes_used_when_reconsidered;
1256
1257/* Value of _bytes_used, when spare_memory was freed. */
1258
1259static size_t bytes_used_when_full;
1260
1261/* This function is used as the hook for free to call. */
1262
1263static void
1264emacs_blocked_free (void *ptr, const void *ptr2)
1265{
1266 BLOCK_INPUT_ALLOC;
1267
1268#ifdef GC_MALLOC_CHECK
1269 if (ptr)
1270 {
1271 struct mem_node *m;
1272
1273 m = mem_find (ptr);
1274 if (m == MEM_NIL || m->start != ptr)
1275 {
1276 fprintf (stderr,
1277 "Freeing `%p' which wasn't allocated with malloc\n", ptr);
1278 emacs_abort ();
1279 }
1280 else
1281 {
1282 /* fprintf (stderr, "free %p...%p (%p)\n", m->start, m->end, ptr); */
1283 mem_delete (m);
1284 }
1285 }
1286#endif /* GC_MALLOC_CHECK */
1287
1288 __free_hook = old_free_hook;
1289 free (ptr);
1290
1291 /* If we released our reserve (due to running out of memory),
1292 and we have a fair amount free once again,
1293 try to set aside another reserve in case we run out once more. */
1294 if (! NILP (Vmemory_full)
1295 /* Verify there is enough space that even with the malloc
1296 hysteresis this call won't run out again.
1297 The code here is correct as long as SPARE_MEMORY
1298 is substantially larger than the block size malloc uses. */
1299 && (bytes_used_when_full
1300 > ((bytes_used_when_reconsidered = BYTES_USED)
1301 + max (malloc_hysteresis, 4) * SPARE_MEMORY)))
1302 refill_memory_reserve ();
1303
1304 __free_hook = emacs_blocked_free;
1305 UNBLOCK_INPUT_ALLOC;
1306}
1307
1308
1309/* This function is the malloc hook that Emacs uses. */
1310
1311static void *
1312emacs_blocked_malloc (size_t size, const void *ptr)
1313{
1314 void *value;
1315
1316 BLOCK_INPUT_ALLOC;
1317 __malloc_hook = old_malloc_hook;
1318#ifdef DOUG_LEA_MALLOC
1319 /* Segfaults on my system. --lorentey */
1320 /* mallopt (M_TOP_PAD, malloc_hysteresis * 4096); */
1321#else
1322 __malloc_extra_blocks = malloc_hysteresis;
1323#endif
1324
1325 value = malloc (size);
1326
1327#ifdef GC_MALLOC_CHECK
1328 {
1329 struct mem_node *m = mem_find (value);
1330 if (m != MEM_NIL)
1331 {
1332 fprintf (stderr, "Malloc returned %p which is already in use\n",
1333 value);
1334 fprintf (stderr, "Region in use is %p...%p, %td bytes, type %d\n",
1335 m->start, m->end, (char *) m->end - (char *) m->start,
1336 m->type);
1337 emacs_abort ();
1338 }
1339
1340 if (!dont_register_blocks)
1341 {
1342 mem_insert (value, (char *) value + max (1, size), allocated_mem_type);
1343 allocated_mem_type = MEM_TYPE_NON_LISP;
1344 }
1345 }
1346#endif /* GC_MALLOC_CHECK */
1347
1348 __malloc_hook = emacs_blocked_malloc;
1349 UNBLOCK_INPUT_ALLOC;
1350
1351 /* fprintf (stderr, "%p malloc\n", value); */
1352 return value;
1353}
1354
1355
1356/* This function is the realloc hook that Emacs uses. */
1357
1358static void *
1359emacs_blocked_realloc (void *ptr, size_t size, const void *ptr2)
1360{
1361 void *value;
1362
1363 BLOCK_INPUT_ALLOC;
1364 __realloc_hook = old_realloc_hook;
1365
1366#ifdef GC_MALLOC_CHECK
1367 if (ptr)
1368 {
1369 struct mem_node *m = mem_find (ptr);
1370 if (m == MEM_NIL || m->start != ptr)
1371 {
1372 fprintf (stderr,
1373 "Realloc of %p which wasn't allocated with malloc\n",
1374 ptr);
1375 emacs_abort ();
1376 }
1377
1378 mem_delete (m);
1379 }
1380
1381 /* fprintf (stderr, "%p -> realloc\n", ptr); */
1382
1383 /* Prevent malloc from registering blocks. */
1384 dont_register_blocks = 1;
1385#endif /* GC_MALLOC_CHECK */
1386
1387 value = realloc (ptr, size);
1388
1389#ifdef GC_MALLOC_CHECK
1390 dont_register_blocks = 0;
1391
1392 {
1393 struct mem_node *m = mem_find (value);
1394 if (m != MEM_NIL)
1395 {
1396 fprintf (stderr, "Realloc returns memory that is already in use\n");
1397 emacs_abort ();
1398 }
1399
1400 /* Can't handle zero size regions in the red-black tree. */
1401 mem_insert (value, (char *) value + max (size, 1), MEM_TYPE_NON_LISP);
1402 }
1403
1404 /* fprintf (stderr, "%p <- realloc\n", value); */
1405#endif /* GC_MALLOC_CHECK */
1406
1407 __realloc_hook = emacs_blocked_realloc;
1408 UNBLOCK_INPUT_ALLOC;
1409
1410 return value;
1411}
1412
1413
1414#ifdef HAVE_PTHREAD
1415/* Called from Fdump_emacs so that when the dumped Emacs starts, it has a
1416 normal malloc. Some thread implementations need this as they call
1417 malloc before main. The pthread_self call in BLOCK_INPUT_ALLOC then
1418 calls malloc because it is the first call, and we have an endless loop. */
1419
1420void
1421reset_malloc_hooks (void)
1422{
1423 __free_hook = old_free_hook;
1424 __malloc_hook = old_malloc_hook;
1425 __realloc_hook = old_realloc_hook;
1426}
1427#endif /* HAVE_PTHREAD */
1428
1429
1430/* Called from main to set up malloc to use our hooks. */
1431
1432void
1433uninterrupt_malloc (void)
1434{
1435#ifdef HAVE_PTHREAD
1436#ifdef DOUG_LEA_MALLOC
1437 pthread_mutexattr_t attr;
1438
1439 /* GLIBC has a faster way to do this, but let's keep it portable.
1440 This is according to the Single UNIX Specification. */
1441 pthread_mutexattr_init (&attr);
1442 pthread_mutexattr_settype (&attr, PTHREAD_MUTEX_RECURSIVE);
1443 pthread_mutex_init (&alloc_mutex, &attr);
1444#else /* !DOUG_LEA_MALLOC */
1445 /* Some systems such as Solaris 2.6 don't have a recursive mutex,
1446 and the bundled gmalloc.c doesn't require it. */
1447 pthread_mutex_init (&alloc_mutex, NULL);
1448#endif /* !DOUG_LEA_MALLOC */
1449#endif /* HAVE_PTHREAD */
1450
1451 if (__free_hook != emacs_blocked_free)
1452 old_free_hook = __free_hook;
1453 __free_hook = emacs_blocked_free;
1454
1455 if (__malloc_hook != emacs_blocked_malloc)
1456 old_malloc_hook = __malloc_hook;
1457 __malloc_hook = emacs_blocked_malloc;
1458
1459 if (__realloc_hook != emacs_blocked_realloc)
1460 old_realloc_hook = __realloc_hook;
1461 __realloc_hook = emacs_blocked_realloc;
1462}
1463
1464#endif /* not SYNC_INPUT */
1465#endif /* not SYSTEM_MALLOC */
1466
1467
1468
1469/*********************************************************************** 1144/***********************************************************************
1470 Interval Allocation 1145 Interval Allocation
1471 ***********************************************************************/ 1146 ***********************************************************************/
@@ -1511,8 +1186,6 @@ make_interval (void)
1511{ 1186{
1512 INTERVAL val; 1187 INTERVAL val;
1513 1188
1514 /* eassert (!handling_signal); */
1515
1516 MALLOC_BLOCK_INPUT; 1189 MALLOC_BLOCK_INPUT;
1517 1190
1518 if (interval_free_list) 1191 if (interval_free_list)
@@ -1896,8 +1569,6 @@ allocate_string (void)
1896{ 1569{
1897 struct Lisp_String *s; 1570 struct Lisp_String *s;
1898 1571
1899 /* eassert (!handling_signal); */
1900
1901 MALLOC_BLOCK_INPUT; 1572 MALLOC_BLOCK_INPUT;
1902 1573
1903 /* If the free-list is empty, allocate a new string_block, and 1574 /* If the free-list is empty, allocate a new string_block, and
@@ -2589,8 +2260,6 @@ make_float (double float_value)
2589{ 2260{
2590 register Lisp_Object val; 2261 register Lisp_Object val;
2591 2262
2592 /* eassert (!handling_signal); */
2593
2594 MALLOC_BLOCK_INPUT; 2263 MALLOC_BLOCK_INPUT;
2595 2264
2596 if (float_free_list) 2265 if (float_free_list)
@@ -2698,8 +2367,6 @@ DEFUN ("cons", Fcons, Scons, 2, 2, 0,
2698{ 2367{
2699 register Lisp_Object val; 2368 register Lisp_Object val;
2700 2369
2701 /* eassert (!handling_signal); */
2702
2703 MALLOC_BLOCK_INPUT; 2370 MALLOC_BLOCK_INPUT;
2704 2371
2705 if (cons_free_list) 2372 if (cons_free_list)
@@ -3205,9 +2872,6 @@ allocate_vectorlike (ptrdiff_t len)
3205 2872
3206 MALLOC_BLOCK_INPUT; 2873 MALLOC_BLOCK_INPUT;
3207 2874
3208 /* This gets triggered by code which I haven't bothered to fix. --Stef */
3209 /* eassert (!handling_signal); */
3210
3211 if (len == 0) 2875 if (len == 0)
3212 p = XVECTOR (zero_vector); 2876 p = XVECTOR (zero_vector);
3213 else 2877 else
@@ -3492,8 +3156,6 @@ Its value and function definition are void, and its property list is nil. */)
3492 3156
3493 CHECK_STRING (name); 3157 CHECK_STRING (name);
3494 3158
3495 /* eassert (!handling_signal); */
3496
3497 MALLOC_BLOCK_INPUT; 3159 MALLOC_BLOCK_INPUT;
3498 3160
3499 if (symbol_free_list) 3161 if (symbol_free_list)
@@ -3578,8 +3240,6 @@ allocate_misc (enum Lisp_Misc_Type type)
3578{ 3240{
3579 Lisp_Object val; 3241 Lisp_Object val;
3580 3242
3581 /* eassert (!handling_signal); */
3582
3583 MALLOC_BLOCK_INPUT; 3243 MALLOC_BLOCK_INPUT;
3584 3244
3585 if (marker_free_list) 3245 if (marker_free_list)
@@ -3799,12 +3459,6 @@ memory_full (size_t nbytes)
3799 lisp_free (spare_memory[i]); 3459 lisp_free (spare_memory[i]);
3800 spare_memory[i] = 0; 3460 spare_memory[i] = 0;
3801 } 3461 }
3802
3803 /* Record the space now used. When it decreases substantially,
3804 we can refill the memory reserve. */
3805#if !defined SYSTEM_MALLOC && !defined SYNC_INPUT
3806 bytes_used_when_full = BYTES_USED;
3807#endif
3808 } 3462 }
3809 3463
3810 /* This used to call error, but if we've run out of memory, we could 3464 /* This used to call error, but if we've run out of memory, we could
@@ -3942,7 +3596,7 @@ mem_insert (void *start, void *end, enum mem_type type)
3942 3596
3943 /* Create a new node. */ 3597 /* Create a new node. */
3944#ifdef GC_MALLOC_CHECK 3598#ifdef GC_MALLOC_CHECK
3945 x = _malloc_internal (sizeof *x); 3599 x = malloc (sizeof *x);
3946 if (x == NULL) 3600 if (x == NULL)
3947 emacs_abort (); 3601 emacs_abort ();
3948#else 3602#else
@@ -4166,7 +3820,7 @@ mem_delete (struct mem_node *z)
4166 mem_delete_fixup (x); 3820 mem_delete_fixup (x);
4167 3821
4168#ifdef GC_MALLOC_CHECK 3822#ifdef GC_MALLOC_CHECK
4169 _free_internal (y); 3823 free (y);
4170#else 3824#else
4171 xfree (y); 3825 xfree (y);
4172#endif 3826#endif
@@ -6767,12 +6421,6 @@ init_alloc_once (void)
6767 init_strings (); 6421 init_strings ();
6768 init_vectors (); 6422 init_vectors ();
6769 6423
6770#ifdef REL_ALLOC
6771 malloc_hysteresis = 32;
6772#else
6773 malloc_hysteresis = 0;
6774#endif
6775
6776 refill_memory_reserve (); 6424 refill_memory_reserve ();
6777 gc_cons_threshold = GC_DEFAULT_THRESHOLD; 6425 gc_cons_threshold = GC_DEFAULT_THRESHOLD;
6778} 6426}
diff --git a/src/atimer.c b/src/atimer.c
index 80b813fe4fe..5dbd807872a 100644
--- a/src/atimer.c
+++ b/src/atimer.c
@@ -369,7 +369,6 @@ run_timers (void)
369 if (! atimers) 369 if (! atimers)
370 pending_atimers = 0; 370 pending_atimers = 0;
371 371
372#ifdef SYNC_INPUT
373 if (pending_atimers) 372 if (pending_atimers)
374 pending_signals = 1; 373 pending_signals = 1;
375 else 374 else
@@ -377,10 +376,6 @@ run_timers (void)
377 pending_signals = interrupt_input_pending; 376 pending_signals = interrupt_input_pending;
378 set_alarm (); 377 set_alarm ();
379 } 378 }
380#else
381 if (! pending_atimers)
382 set_alarm ();
383#endif
384} 379}
385 380
386 381
@@ -391,11 +386,7 @@ static void
391handle_alarm_signal (int sig) 386handle_alarm_signal (int sig)
392{ 387{
393 pending_atimers = 1; 388 pending_atimers = 1;
394#ifdef SYNC_INPUT
395 pending_signals = 1; 389 pending_signals = 1;
396#else
397 run_timers ();
398#endif
399} 390}
400 391
401static void 392static void
diff --git a/src/bytecode.c b/src/bytecode.c
index b151078f60f..5f4fdcc5eff 100644
--- a/src/bytecode.c
+++ b/src/bytecode.c
@@ -458,7 +458,8 @@ unmark_byte_stack (void)
458 Fsignal (Qquit, Qnil); \ 458 Fsignal (Qquit, Qnil); \
459 AFTER_POTENTIAL_GC (); \ 459 AFTER_POTENTIAL_GC (); \
460 } \ 460 } \
461 ELSE_PENDING_SIGNALS \ 461 else if (pending_signals) \
462 process_pending_signals (); \
462 } while (0) 463 } while (0)
463 464
464 465
diff --git a/src/conf_post.h b/src/conf_post.h
index 94934ffeadf..0c4d029bc5d 100644
--- a/src/conf_post.h
+++ b/src/conf_post.h
@@ -90,7 +90,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
90char *_getpty(); 90char *_getpty();
91#endif 91#endif
92 92
93#undef SA_RESTART /* not the same as defining BROKEN_SA_RESTART */
94#endif /* IRIX6_5 */ 93#endif /* IRIX6_5 */
95 94
96#ifdef MSDOS 95#ifdef MSDOS
diff --git a/src/emacs.c b/src/emacs.c
index 1416bf76c43..233c0e68a14 100644
--- a/src/emacs.c
+++ b/src/emacs.c
@@ -848,14 +848,10 @@ main (int argc, char **argv)
848 /* Arrange to get warning messages as memory fills up. */ 848 /* Arrange to get warning messages as memory fills up. */
849 memory_warnings (0, malloc_warning); 849 memory_warnings (0, malloc_warning);
850 850
851 /* Call malloc at least once, to run the initial __malloc_hook. 851 /* Call malloc at least once, to run malloc_initialize_hook.
852 Also call realloc and free for consistency. */ 852 Also call realloc and free for consistency. */
853 free (realloc (malloc (4), 4)); 853 free (realloc (malloc (4), 4));
854 854
855# ifndef SYNC_INPUT
856 /* Arrange to disable interrupt input inside malloc etc. */
857 uninterrupt_malloc ();
858# endif /* not SYNC_INPUT */
859#endif /* not SYSTEM_MALLOC */ 855#endif /* not SYSTEM_MALLOC */
860 856
861#if defined (MSDOS) || defined (WINDOWSNT) 857#if defined (MSDOS) || defined (WINDOWSNT)
@@ -2143,12 +2139,6 @@ You must run Emacs in batch mode in order to dump it. */)
2143 memory_warnings (my_edata, malloc_warning); 2139 memory_warnings (my_edata, malloc_warning);
2144 } 2140 }
2145#endif /* not WINDOWSNT */ 2141#endif /* not WINDOWSNT */
2146#if defined (HAVE_PTHREAD) && !defined SYNC_INPUT
2147 /* Pthread may call malloc before main, and then we will get an endless
2148 loop, because pthread_self (see alloc.c) calls malloc the first time
2149 it is called on some systems. */
2150 reset_malloc_hooks ();
2151#endif
2152#endif /* not SYSTEM_MALLOC */ 2142#endif /* not SYSTEM_MALLOC */
2153#ifdef DOUG_LEA_MALLOC 2143#ifdef DOUG_LEA_MALLOC
2154 malloc_state_ptr = malloc_get_state (); 2144 malloc_state_ptr = malloc_get_state ();
diff --git a/src/eval.c b/src/eval.c
index 6cca13a8fda..1c565e233c6 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -117,12 +117,6 @@ static EMACS_INT when_entered_debugger;
117 117
118Lisp_Object Vsignaling_function; 118Lisp_Object Vsignaling_function;
119 119
120/* Set to non-zero while processing X events. Checked in Feval to
121 make sure the Lisp interpreter isn't called from a signal handler,
122 which is unsafe because the interpreter isn't reentrant. */
123
124int handling_signal;
125
126/* If non-nil, Lisp code must not be run since some part of Emacs is 120/* If non-nil, Lisp code must not be run since some part of Emacs is
127 in an inconsistent state. Currently, x-create-frame uses this to 121 in an inconsistent state. Currently, x-create-frame uses this to
128 avoid triggering window-configuration-change-hook while the new 122 avoid triggering window-configuration-change-hook while the new
@@ -1106,7 +1100,6 @@ unwind_to_catch (struct catchtag *catch, Lisp_Object value)
1106 /* Restore certain special C variables. */ 1100 /* Restore certain special C variables. */
1107 set_poll_suppress_count (catch->poll_suppress_count); 1101 set_poll_suppress_count (catch->poll_suppress_count);
1108 UNBLOCK_INPUT_TO (catch->interrupt_input_blocked); 1102 UNBLOCK_INPUT_TO (catch->interrupt_input_blocked);
1109 handling_signal = 0;
1110 immediate_quit = 0; 1103 immediate_quit = 0;
1111 1104
1112 do 1105 do
@@ -1486,7 +1479,7 @@ See also the function `condition-case'. */)
1486 struct handler *h; 1479 struct handler *h;
1487 struct backtrace *bp; 1480 struct backtrace *bp;
1488 1481
1489 immediate_quit = handling_signal = 0; 1482 immediate_quit = 0;
1490 abort_on_gc = 0; 1483 abort_on_gc = 0;
1491 if (gc_in_progress || waiting_for_input) 1484 if (gc_in_progress || waiting_for_input)
1492 emacs_abort (); 1485 emacs_abort ();
@@ -2039,9 +2032,6 @@ eval_sub (Lisp_Object form)
2039 struct backtrace backtrace; 2032 struct backtrace backtrace;
2040 struct gcpro gcpro1, gcpro2, gcpro3; 2033 struct gcpro gcpro1, gcpro2, gcpro3;
2041 2034
2042 if (handling_signal)
2043 emacs_abort ();
2044
2045 if (SYMBOLP (form)) 2035 if (SYMBOLP (form))
2046 { 2036 {
2047 /* Look up its binding in the lexical environment. 2037 /* Look up its binding in the lexical environment.
@@ -3104,8 +3094,6 @@ specbind (Lisp_Object symbol, Lisp_Object value)
3104{ 3094{
3105 struct Lisp_Symbol *sym; 3095 struct Lisp_Symbol *sym;
3106 3096
3107 eassert (!handling_signal);
3108
3109 CHECK_SYMBOL (symbol); 3097 CHECK_SYMBOL (symbol);
3110 sym = XSYMBOL (symbol); 3098 sym = XSYMBOL (symbol);
3111 if (specpdl_ptr == specpdl + specpdl_size) 3099 if (specpdl_ptr == specpdl + specpdl_size)
@@ -3199,8 +3187,6 @@ specbind (Lisp_Object symbol, Lisp_Object value)
3199void 3187void
3200record_unwind_protect (Lisp_Object (*function) (Lisp_Object), Lisp_Object arg) 3188record_unwind_protect (Lisp_Object (*function) (Lisp_Object), Lisp_Object arg)
3201{ 3189{
3202 eassert (!handling_signal);
3203
3204 if (specpdl_ptr == specpdl + specpdl_size) 3190 if (specpdl_ptr == specpdl + specpdl_size)
3205 grow_specpdl (); 3191 grow_specpdl ();
3206 specpdl_ptr->func = function; 3192 specpdl_ptr->func = function;
diff --git a/src/intervals.c b/src/intervals.c
index 5a47cacb2dd..584ee1e923d 100644
--- a/src/intervals.c
+++ b/src/intervals.c
@@ -673,8 +673,7 @@ find_interval (register INTERVAL tree, register ptrdiff_t position)
673 673
674 eassert (relative_position <= TOTAL_LENGTH (tree)); 674 eassert (relative_position <= TOTAL_LENGTH (tree));
675 675
676 if (!handling_signal) 676 tree = balance_possible_root_interval (tree);
677 tree = balance_possible_root_interval (tree);
678 677
679 while (1) 678 while (1)
680 { 679 {
diff --git a/src/keyboard.c b/src/keyboard.c
index d164083fb86..01644b3832d 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -84,9 +84,7 @@ int interrupt_input_pending;
84 pending_atimers separately, to reduce code size. So, any code that 84 pending_atimers separately, to reduce code size. So, any code that
85 changes interrupt_input_pending or pending_atimers should update 85 changes interrupt_input_pending or pending_atimers should update
86 this too. */ 86 this too. */
87#ifdef SYNC_INPUT
88int pending_signals; 87int pending_signals;
89#endif
90 88
91#define KBD_BUFFER_SIZE 4096 89#define KBD_BUFFER_SIZE 4096
92 90
@@ -2010,17 +2008,9 @@ static struct atimer *poll_timer;
2010void 2008void
2011poll_for_input_1 (void) 2009poll_for_input_1 (void)
2012{ 2010{
2013/* Tell ns_read_socket() it is being called asynchronously so it can avoid
2014 doing anything dangerous. */
2015#ifdef HAVE_NS
2016 ++handling_signal;
2017#endif
2018 if (interrupt_input_blocked == 0 2011 if (interrupt_input_blocked == 0
2019 && !waiting_for_input) 2012 && !waiting_for_input)
2020 read_avail_input (0); 2013 read_avail_input (0);
2021#ifdef HAVE_NS
2022 --handling_signal;
2023#endif
2024} 2014}
2025 2015
2026/* Timer callback function for poll_timer. TIMER is equal to 2016/* Timer callback function for poll_timer. TIMER is equal to
@@ -2031,12 +2021,8 @@ poll_for_input (struct atimer *timer)
2031{ 2021{
2032 if (poll_suppress_count == 0) 2022 if (poll_suppress_count == 0)
2033 { 2023 {
2034#ifdef SYNC_INPUT
2035 interrupt_input_pending = 1; 2024 interrupt_input_pending = 1;
2036 pending_signals = 1; 2025 pending_signals = 1;
2037#else
2038 poll_for_input_1 ();
2039#endif
2040 } 2026 }
2041} 2027}
2042 2028
@@ -7176,19 +7162,12 @@ tty_read_avail_input (struct terminal *terminal,
7176 return nread; 7162 return nread;
7177} 7163}
7178 7164
7179#if defined SYNC_INPUT || defined USABLE_SIGIO
7180static void 7165static void
7181handle_async_input (void) 7166handle_async_input (void)
7182{ 7167{
7183 interrupt_input_pending = 0; 7168 interrupt_input_pending = 0;
7184#ifdef SYNC_INPUT
7185 pending_signals = pending_atimers; 7169 pending_signals = pending_atimers;
7186#endif 7170
7187/* Tell ns_read_socket() it is being called asynchronously so it can avoid
7188 doing anything dangerous. */
7189#ifdef HAVE_NS
7190 ++handling_signal;
7191#endif
7192 while (1) 7171 while (1)
7193 { 7172 {
7194 int nread; 7173 int nread;
@@ -7199,13 +7178,8 @@ handle_async_input (void)
7199 if (nread <= 0) 7178 if (nread <= 0)
7200 break; 7179 break;
7201 } 7180 }
7202#ifdef HAVE_NS
7203 --handling_signal;
7204#endif
7205} 7181}
7206#endif /* SYNC_INPUT || USABLE_SIGIO */
7207 7182
7208#ifdef SYNC_INPUT
7209void 7183void
7210process_pending_signals (void) 7184process_pending_signals (void)
7211{ 7185{
@@ -7213,24 +7187,17 @@ process_pending_signals (void)
7213 handle_async_input (); 7187 handle_async_input ();
7214 do_pending_atimers (); 7188 do_pending_atimers ();
7215} 7189}
7216#endif
7217 7190
7218#ifdef USABLE_SIGIO 7191#ifdef USABLE_SIGIO
7219 7192
7220static void 7193static void
7221handle_input_available_signal (int sig) 7194handle_input_available_signal (int sig)
7222{ 7195{
7223#ifdef SYNC_INPUT
7224 interrupt_input_pending = 1; 7196 interrupt_input_pending = 1;
7225 pending_signals = 1; 7197 pending_signals = 1;
7226#endif
7227 7198
7228 if (input_available_clear_time) 7199 if (input_available_clear_time)
7229 *input_available_clear_time = make_emacs_time (0, 0); 7200 *input_available_clear_time = make_emacs_time (0, 0);
7230
7231#ifndef SYNC_INPUT
7232 handle_async_input ();
7233#endif
7234} 7201}
7235 7202
7236static void 7203static void
@@ -11365,9 +11332,7 @@ init_keyboard (void)
11365 input_pending = 0; 11332 input_pending = 0;
11366 interrupt_input_blocked = 0; 11333 interrupt_input_blocked = 0;
11367 interrupt_input_pending = 0; 11334 interrupt_input_pending = 0;
11368#ifdef SYNC_INPUT
11369 pending_signals = 0; 11335 pending_signals = 0;
11370#endif
11371 11336
11372 /* This means that command_loop_1 won't try to select anything the first 11337 /* This means that command_loop_1 won't try to select anything the first
11373 time through. */ 11338 time through. */
diff --git a/src/lisp.h b/src/lisp.h
index 447c6bd296b..3a473a60b48 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -2107,22 +2107,16 @@ extern char *stack_bottom;
2107 If quit-flag is set to `kill-emacs' the SIGINT handler has received 2107 If quit-flag is set to `kill-emacs' the SIGINT handler has received
2108 a request to exit Emacs when it is safe to do. */ 2108 a request to exit Emacs when it is safe to do. */
2109 2109
2110#ifdef SYNC_INPUT
2111extern void process_pending_signals (void); 2110extern void process_pending_signals (void);
2112extern int pending_signals; 2111extern int pending_signals;
2113#define ELSE_PENDING_SIGNALS \
2114 else if (pending_signals) \
2115 process_pending_signals ();
2116#else /* not SYNC_INPUT */
2117#define ELSE_PENDING_SIGNALS
2118#endif /* not SYNC_INPUT */
2119 2112
2120extern void process_quit_flag (void); 2113extern void process_quit_flag (void);
2121#define QUIT \ 2114#define QUIT \
2122 do { \ 2115 do { \
2123 if (!NILP (Vquit_flag) && NILP (Vinhibit_quit)) \ 2116 if (!NILP (Vquit_flag) && NILP (Vinhibit_quit)) \
2124 process_quit_flag (); \ 2117 process_quit_flag (); \
2125 ELSE_PENDING_SIGNALS \ 2118 else if (pending_signals) \
2119 process_pending_signals (); \
2126 } while (0) 2120 } while (0)
2127 2121
2128 2122
@@ -2846,8 +2840,6 @@ extern void memory_warnings (void *, void (*warnfun) (const char *));
2846/* Defined in alloc.c. */ 2840/* Defined in alloc.c. */
2847extern void check_pure_size (void); 2841extern void check_pure_size (void);
2848extern void allocate_string_data (struct Lisp_String *, EMACS_INT, EMACS_INT); 2842extern void allocate_string_data (struct Lisp_String *, EMACS_INT, EMACS_INT);
2849extern void reset_malloc_hooks (void);
2850extern void uninterrupt_malloc (void);
2851extern void malloc_warning (const char *); 2843extern void malloc_warning (const char *);
2852extern _Noreturn void memory_full (size_t); 2844extern _Noreturn void memory_full (size_t);
2853extern _Noreturn void buffer_memory_full (ptrdiff_t); 2845extern _Noreturn void buffer_memory_full (ptrdiff_t);
@@ -3043,7 +3035,6 @@ extern Lisp_Object Qand_rest;
3043extern Lisp_Object Vautoload_queue; 3035extern Lisp_Object Vautoload_queue;
3044extern Lisp_Object Vsignaling_function; 3036extern Lisp_Object Vsignaling_function;
3045extern Lisp_Object inhibit_lisp_code; 3037extern Lisp_Object inhibit_lisp_code;
3046extern int handling_signal;
3047#if BYTE_MARK_STACK 3038#if BYTE_MARK_STACK
3048extern struct catchtag *catchlist; 3039extern struct catchtag *catchlist;
3049extern struct handler *handlerlist; 3040extern struct handler *handlerlist;
diff --git a/src/nsmenu.m b/src/nsmenu.m
index 3057f4f6a20..907d3eac622 100644
--- a/src/nsmenu.m
+++ b/src/nsmenu.m
@@ -588,10 +588,7 @@ extern NSString *NSMenuDidBeginTrackingNotification;
588 From 10.6 on, we could also use -[NSMenu propertiesToUpdate]: In the 588 From 10.6 on, we could also use -[NSMenu propertiesToUpdate]: In the
589 key press case, NSMenuPropertyItemImage (e.g.) won't be set. 589 key press case, NSMenuPropertyItemImage (e.g.) won't be set.
590 */ 590 */
591 if (trackingMenu == 0 591 if (trackingMenu == 0)
592 /* Also, don't try this if from an event picked up asynchronously,
593 as lots of lisp evaluation happens in ns_update_menubar. */
594 || handling_signal != 0)
595 return; 592 return;
596/*fprintf (stderr, "Updating menu '%s'\n", [[self title] UTF8String]); NSLog (@"%@\n", event); */ 593/*fprintf (stderr, "Updating menu '%s'\n", [[self title] UTF8String]); NSLog (@"%@\n", event); */
597 ns_update_menubar (frame, 1, self); 594 ns_update_menubar (frame, 1, self);
diff --git a/src/nsterm.m b/src/nsterm.m
index 41520ce74d1..0b26508dbd0 100644
--- a/src/nsterm.m
+++ b/src/nsterm.m
@@ -3355,16 +3355,12 @@ ns_read_socket (struct terminal *terminal, int expected,
3355 if (interrupt_input_blocked) 3355 if (interrupt_input_blocked)
3356 { 3356 {
3357 interrupt_input_pending = 1; 3357 interrupt_input_pending = 1;
3358#ifdef SYNC_INPUT
3359 pending_signals = 1; 3358 pending_signals = 1;
3360#endif
3361 return -1; 3359 return -1;
3362 } 3360 }
3363 3361
3364 interrupt_input_pending = 0; 3362 interrupt_input_pending = 0;
3365#ifdef SYNC_INPUT
3366 pending_signals = pending_atimers; 3363 pending_signals = pending_atimers;
3367#endif
3368 3364
3369 BLOCK_INPUT; 3365 BLOCK_INPUT;
3370 n_emacs_events_pending = 0; 3366 n_emacs_events_pending = 0;
@@ -3726,7 +3722,7 @@ ns_judge_scroll_bars (struct frame *f)
3726 removed = YES; 3722 removed = YES;
3727 } 3723 }
3728 3724
3729 if (removed) 3725 if (removed)
3730 [eview updateFrameSize: NO]; 3726 [eview updateFrameSize: NO];
3731} 3727}
3732 3728
@@ -3988,7 +3984,6 @@ ns_term_init (Lisp_Object display_name)
3988 /* count object allocs (About, click icon); on OS X use ObjectAlloc tool */ 3984 /* count object allocs (About, click icon); on OS X use ObjectAlloc tool */
3989 /*GSDebugAllocationActive (YES); */ 3985 /*GSDebugAllocationActive (YES); */
3990 BLOCK_INPUT; 3986 BLOCK_INPUT;
3991 handling_signal = 0;
3992 3987
3993 baud_rate = 38400; 3988 baud_rate = 38400;
3994 Fset_input_interrupt_mode (Qnil); 3989 Fset_input_interrupt_mode (Qnil);
@@ -6239,7 +6234,7 @@ not_in_argv (NSString *arg)
6239 NSRect r = [super constrainFrameRect:frameRect toScreen:screen]; 6234 NSRect r = [super constrainFrameRect:frameRect toScreen:screen];
6240 return r; 6235 return r;
6241 } 6236 }
6242 6237
6243 if (f->output_data.ns->dont_constrain 6238 if (f->output_data.ns->dont_constrain
6244 || ns_menu_bar_should_be_hidden ()) 6239 || ns_menu_bar_should_be_hidden ())
6245 return frameRect; 6240 return frameRect;
diff --git a/src/process.c b/src/process.c
index 6dbff6f4b16..a371dece250 100644
--- a/src/process.c
+++ b/src/process.c
@@ -4395,10 +4395,8 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd,
4395 Otherwise, do pending quit if requested. */ 4395 Otherwise, do pending quit if requested. */
4396 if (read_kbd >= 0) 4396 if (read_kbd >= 0)
4397 QUIT; 4397 QUIT;
4398#ifdef SYNC_INPUT
4399 else 4398 else
4400 process_pending_signals (); 4399 process_pending_signals ();
4401#endif
4402 4400
4403 /* Exit now if the cell we're waiting for became non-nil. */ 4401 /* Exit now if the cell we're waiting for became non-nil. */
4404 if (! NILP (wait_for_cell) && ! NILP (XCAR (wait_for_cell))) 4402 if (! NILP (wait_for_cell) && ! NILP (XCAR (wait_for_cell)))
diff --git a/src/regex.c b/src/regex.c
index 92264ccae23..17562043df1 100644
--- a/src/regex.c
+++ b/src/regex.c
@@ -1831,9 +1831,9 @@ typedef struct
1831/* The next available element. */ 1831/* The next available element. */
1832#define COMPILE_STACK_TOP (compile_stack.stack[compile_stack.avail]) 1832#define COMPILE_STACK_TOP (compile_stack.stack[compile_stack.avail])
1833 1833
1834/* Explicit quit checking is only used on NTemacs and whenever we 1834/* Explicit quit checking is needed for Emacs, which uses polling to
1835 use polling to process input events. */ 1835 process input events. */
1836#if defined emacs && (defined WINDOWSNT || defined SYNC_INPUT) && defined QUIT 1836#ifdef emacs
1837extern int immediate_quit; 1837extern int immediate_quit;
1838# define IMMEDIATE_QUIT_CHECK \ 1838# define IMMEDIATE_QUIT_CHECK \
1839 do { \ 1839 do { \
diff --git a/src/sysdep.c b/src/sysdep.c
index 9065b38d6fc..dbfd9efc7d4 100644
--- a/src/sysdep.c
+++ b/src/sysdep.c
@@ -1447,27 +1447,21 @@ emacs_sigaction_init (struct sigaction *action, signal_handler_t handler)
1447 action->sa_handler = handler; 1447 action->sa_handler = handler;
1448 action->sa_flags = 0; 1448 action->sa_flags = 0;
1449#if defined (SA_RESTART) 1449#if defined (SA_RESTART)
1450 /* Emacs mostly works better with restartable system services. If this 1450 /* SA_RESTART causes interruptible functions with timeouts (e.g.,
1451 flag exists, we probably want to turn it on here. 1451 'select') to reset their timeout on some platforms (e.g.,
1452 However, on some systems (only hpux11 at present) this resets the 1452 HP-UX 11), which is not what we want. Also, when Emacs is
1453 timeout of `select' which means that `select' never finishes if 1453 interactive, we don't want SA_RESTART because we need to poll
1454 it keeps getting signals.
1455 We define BROKEN_SA_RESTART on those systems. */
1456 /* It's not clear why the comment above says "mostly works better". --Stef
1457 When SYNC_INPUT is set, we don't want SA_RESTART because we need to poll
1458 for pending input so we need long-running syscalls to be interrupted 1454 for pending input so we need long-running syscalls to be interrupted
1459 after a signal that sets the interrupt_input_pending flag. */ 1455 after a signal that sets the interrupt_input_pending flag. */
1460 /* Non-interactive keyboard input goes through stdio, where we always 1456 /* Non-interactive keyboard input goes through stdio, where we always
1461 want restartable system calls. */ 1457 want restartable system calls. */
1462# if defined (BROKEN_SA_RESTART) || defined (SYNC_INPUT)
1463 if (noninteractive) 1458 if (noninteractive)
1464# endif
1465 action->sa_flags = SA_RESTART; 1459 action->sa_flags = SA_RESTART;
1466#endif 1460#endif
1467} 1461}
1468 1462
1469#ifdef FORWARD_SIGNAL_TO_MAIN_THREAD 1463#ifdef FORWARD_SIGNAL_TO_MAIN_THREAD
1470pthread_t main_thread; 1464static pthread_t main_thread;
1471#endif 1465#endif
1472 1466
1473/* If we are on the main thread, handle the signal SIG with HANDLER. 1467/* If we are on the main thread, handle the signal SIG with HANDLER.
@@ -1914,11 +1908,9 @@ emacs_write (int fildes, const char *buf, ptrdiff_t nbyte)
1914 { 1908 {
1915 if (errno == EINTR) 1909 if (errno == EINTR)
1916 { 1910 {
1917#ifdef SYNC_INPUT
1918 /* I originally used `QUIT' but that might causes files to 1911 /* I originally used `QUIT' but that might causes files to
1919 be truncated if you hit C-g in the middle of it. --Stef */ 1912 be truncated if you hit C-g in the middle of it. --Stef */
1920 process_pending_signals (); 1913 process_pending_signals ();
1921#endif
1922 continue; 1914 continue;
1923 } 1915 }
1924 else 1916 else
diff --git a/src/syssignal.h b/src/syssignal.h
index 5e733dd812d..e309e6725b7 100644
--- a/src/syssignal.h
+++ b/src/syssignal.h
@@ -64,8 +64,4 @@ extern void emacs_sigaction_init (struct sigaction *, signal_handler_t);
64char *strsignal (int); 64char *strsignal (int);
65#endif 65#endif
66 66
67#ifdef FORWARD_SIGNAL_TO_MAIN_THREAD
68extern pthread_t main_thread;
69#endif
70
71void handle_on_main_thread (int, signal_handler_t); 67void handle_on_main_thread (int, signal_handler_t);
diff --git a/src/xdisp.c b/src/xdisp.c
index 8e0975cf65a..5ee5a46601c 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -9290,12 +9290,6 @@ add_to_log (const char *format, Lisp_Object arg1, Lisp_Object arg2)
9290 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4; 9290 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
9291 USE_SAFE_ALLOCA; 9291 USE_SAFE_ALLOCA;
9292 9292
9293 /* Do nothing if called asynchronously. Inserting text into
9294 a buffer may call after-change-functions and alike and
9295 that would means running Lisp asynchronously. */
9296 if (handling_signal)
9297 return;
9298
9299 fmt = msg = Qnil; 9293 fmt = msg = Qnil;
9300 GCPRO4 (fmt, msg, arg1, arg2); 9294 GCPRO4 (fmt, msg, arg1, arg2);
9301 9295
diff --git a/src/xterm.c b/src/xterm.c
index 900a1d78b80..9ab53dc087a 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -7129,25 +7129,17 @@ XTread_socket (struct terminal *terminal, int expected, struct input_event *hold
7129 if (interrupt_input_blocked) 7129 if (interrupt_input_blocked)
7130 { 7130 {
7131 interrupt_input_pending = 1; 7131 interrupt_input_pending = 1;
7132#ifdef SYNC_INPUT
7133 pending_signals = 1; 7132 pending_signals = 1;
7134#endif
7135 return -1; 7133 return -1;
7136 } 7134 }
7137 7135
7138 interrupt_input_pending = 0; 7136 interrupt_input_pending = 0;
7139#ifdef SYNC_INPUT
7140 pending_signals = pending_atimers; 7137 pending_signals = pending_atimers;
7141#endif
7142 BLOCK_INPUT; 7138 BLOCK_INPUT;
7143 7139
7144 /* So people can tell when we have read the available input. */ 7140 /* So people can tell when we have read the available input. */
7145 input_signal_count++; 7141 input_signal_count++;
7146 7142
7147#ifndef SYNC_INPUT
7148 ++handling_signal;
7149#endif
7150
7151 /* For debugging, this gives a way to fake an I/O error. */ 7143 /* For debugging, this gives a way to fake an I/O error. */
7152 if (terminal->display_info.x == XTread_socket_fake_io_error) 7144 if (terminal->display_info.x == XTread_socket_fake_io_error)
7153 { 7145 {
@@ -7236,9 +7228,6 @@ XTread_socket (struct terminal *terminal, int expected, struct input_event *hold
7236 pending_autoraise_frame = 0; 7228 pending_autoraise_frame = 0;
7237 } 7229 }
7238 7230
7239#ifndef SYNC_INPUT
7240 --handling_signal;
7241#endif
7242 UNBLOCK_INPUT; 7231 UNBLOCK_INPUT;
7243 7232
7244 return count; 7233 return count;
@@ -7788,7 +7777,6 @@ x_connection_closed (Display *dpy, const char *error_message)
7788 7777
7789 error_msg = alloca (strlen (error_message) + 1); 7778 error_msg = alloca (strlen (error_message) + 1);
7790 strcpy (error_msg, error_message); 7779 strcpy (error_msg, error_message);
7791 handling_signal = 0;
7792 7780
7793 /* Inhibit redisplay while frames are being deleted. */ 7781 /* Inhibit redisplay while frames are being deleted. */
7794 specbind (Qinhibit_redisplay, Qt); 7782 specbind (Qinhibit_redisplay, Qt);