From 0caaedb1c3c9c48980144e41d2a95329d39c399a Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Sun, 16 Sep 2012 14:43:55 -0700 Subject: [PATCH] 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 . * 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 --- ChangeLog | 5 + admin/CPP-DEFINES | 2 - admin/ChangeLog | 5 + configure.ac | 10 -- etc/ChangeLog | 6 + etc/TODO | 7 - src/ChangeLog | 42 +++++ src/alloc.c | 424 ++++------------------------------------------ src/atimer.c | 9 - src/bytecode.c | 3 +- src/conf_post.h | 1 - src/emacs.c | 12 +- src/eval.c | 16 +- src/intervals.c | 3 +- src/keyboard.c | 37 +--- src/lisp.h | 13 +- src/nsmenu.m | 5 +- src/nsterm.m | 9 +- src/process.c | 2 - src/regex.c | 6 +- src/sysdep.c | 18 +- src/syssignal.h | 4 - src/xdisp.c | 6 - src/xterm.c | 12 -- 24 files changed, 113 insertions(+), 544 deletions(-) diff --git a/ChangeLog b/ChangeLog index 5dadc44ebd..4bdca0c914 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2012-09-16 Paul Eggert + + Remove configure's --without-sync-input option (Bug#12450). + * configure.ac (SYNC_INPUT, BROKEN_SA_RESTART): Remove. + 2012-09-16 Glenn Morris Increase compartmentalization of Nextstep builds rules, diff --git a/admin/CPP-DEFINES b/admin/CPP-DEFINES index 834695d6c7..661cde9c43 100644 --- a/admin/CPP-DEFINES +++ b/admin/CPP-DEFINES @@ -90,7 +90,6 @@ BROKEN_GETWD BROKEN_GET_CURRENT_DIR_NAME BROKEN_NON_BLOCKING_CONNECT BROKEN_PTY_READ_AFTER_EAGAIN -BROKEN_SA_RESTART CLASH_DETECTION DATA_SEG_BITS DATA_START @@ -434,7 +433,6 @@ PTY_OPEN PTY_TTY_NAME_SPRINTF PURESIZE RUN_TIME_REMAP -SA_RESTART SETPGRP_RELEASES_CTTY SETUP_SLAVE_PTY SIGALRM diff --git a/admin/ChangeLog b/admin/ChangeLog index 27765a078f..8fe16b9e76 100644 --- a/admin/ChangeLog +++ b/admin/ChangeLog @@ -1,3 +1,8 @@ +2012-09-16 Paul Eggert + + Remove configure's --without-sync-input option (Bug#12450). + * CPP-DEFINES (BROKEN_SA_RESTART, SA_RESTART): Remove. + 2012-09-16 Glenn Morris * admin.el (set-version): No more need to set nextstep versions. diff --git a/configure.ac b/configure.ac index 38a7613d84..569b367371 100644 --- a/configure.ac +++ b/configure.ac @@ -128,11 +128,6 @@ AC_ARG_WITH([mailhost],[AS_HELP_STRING([--with-mailhost=HOSTNAME], OPTION_DEFAULT_ON([sound],[don't compile with sound support]) -OPTION_DEFAULT_ON([sync-input],[don't process async input synchronously]) -if test "$with_sync_input" = yes; then - AC_DEFINE(SYNC_INPUT, 1, [Process async input synchronously.]) -fi - dnl FIXME currently it is not the last. dnl This should be the last --with option, because --with-x is dnl added later on when we find the path of X, and it's best to @@ -3949,11 +3944,6 @@ case $opsys in ;; hpux11) - dnl See comments in sysdep.c:sys_signal. - dnl SA_RESTART resets the timeout of `select' on hpux11. - dnl Defining BROKEN_SA_RESTART is not the same as undef'ing SA_RESTART. - AC_DEFINE(BROKEN_SA_RESTART, 1, [Define if SA_RESTART should only - be used in batch mode.]) dnl It works to open the pty's tty in the parent (Emacs), then dnl close and reopen it in the child. AC_DEFINE(USG_SUBTTY_WORKS, 1, [Define for USG systems where it diff --git a/etc/ChangeLog b/etc/ChangeLog index 66c229eaf7..5a14c523cf 100644 --- a/etc/ChangeLog +++ b/etc/ChangeLog @@ -1,3 +1,9 @@ +2012-09-16 Paul Eggert + + Remove configure's --without-sync-input option (Bug#12450). + * TODO (Make SYNC_INPUT the default): Remove, as the code now + behaves as if SYNC_INPUT is always true. + 2012-09-13 Paul Eggert Use a more backwards-compatible timer format (Bug#12430). diff --git a/etc/TODO b/etc/TODO index 50e3bd64b9..be0ef95aed 100644 --- a/etc/TODO +++ b/etc/TODO @@ -1229,13 +1229,6 @@ systems for HTML/XML files automatically." For use by sml-mode, python-mode, tex-mode, scheme-mode, lisp-mode, haskell-mode, tuareg-mode, ... -** Make SYNC_INPUT the default. [true since 2008-03-11] - All loops using immediate_quit need to be checked to ensure that - C-g can interrupt them, in case of an infinite loop. Once we - switch to using SYNC_INPUT, we can remove the BLOCK_INPUTs in the - allocation functions (allocate_string etc.) without worrying about - data munging. - ** Add "link" button class Add a standard button-class named "link", and make all other link-like button classes inherit from it. Set the default face of the "link" button diff --git a/src/ChangeLog b/src/ChangeLog index 32cd7b3e81..f21395d963 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,5 +1,47 @@ 2012-09-16 Paul Eggert + Remove configure's --without-sync-input option (Bug#12450). + 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 . + * 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. + * atimer.c (run_timers, handle_alarm_signal): + * keyboard.c (pending_signal, poll_for_input_1, poll_for_input) + (handle_async_input, process_pending_signals) + (handle_input_available_signal, init_keyboard): + * nsterm.m (ns_read_socket): + * process.c (wait_reading_process_output): + * regex.c (immediate_quit, IMMEDIATE_QUIT_CHECK): + * sysdep.c (emacs_sigaction_init) [SA_RESTART]: + (emacs_write): + * xterm.c (XTread_socket): + Assume SYNC_INPUT. + * conf_post.h (SA_RESTART) [IRIX6_5]: Do not #undef. + * eval.c (handling_signal): Remove. All uses removed. + * lisp.h (ELSE_PENDING_SIGNALS): Remove. + All uses replaced with the SYNC_INPUT version. + (reset_malloc_hooks, uninterrupt_malloc, handling_signal): + Remove decls. + * sysdep.c, syssignal.h (main_thread) [FORWARD_SIGNAL_TO_MAIN_THREAD]: + Now static. + * font.c (Ffont_shape_gstring): Remove unused local. 2012-09-16 Glenn Morris diff --git a/src/alloc.c b/src/alloc.c index 0bfbb0c88b..fb7d35b559 100644 --- a/src/alloc.c +++ b/src/alloc.c @@ -85,68 +85,8 @@ extern void *sbrk (); #define MMAP_MAX_AREAS 100000000 -#else /* not DOUG_LEA_MALLOC */ - -/* The following come from gmalloc.c. */ - -extern size_t _bytes_used; -extern size_t __malloc_extra_blocks; -extern void *_malloc_internal (size_t); -extern void _free_internal (void *); - #endif /* not DOUG_LEA_MALLOC */ -#if ! defined SYSTEM_MALLOC && ! defined SYNC_INPUT -#ifdef HAVE_PTHREAD - -# include "syssignal.h" - -/* When GTK uses the file chooser dialog, different backends can be loaded - dynamically. One such a backend is the Gnome VFS backend that gets loaded - if you run Gnome. That backend creates several threads and also allocates - memory with malloc. - - Also, gconf and gsettings may create several threads. - - 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 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). - - When UNBLOCK_INPUT is called, reinvoke_input_signal may be called. If this - happens in one of the backend threads we will have two threads that tries - to run Emacs code at once, and the code is not prepared for that. - To prevent that, we only call BLOCK/UNBLOCK from the main thread. */ - -static pthread_mutex_t alloc_mutex; - -#define BLOCK_INPUT_ALLOC \ - do \ - { \ - if (pthread_equal (pthread_self (), main_thread)) \ - BLOCK_INPUT; \ - pthread_mutex_lock (&alloc_mutex); \ - } \ - while (0) -#define UNBLOCK_INPUT_ALLOC \ - do \ - { \ - pthread_mutex_unlock (&alloc_mutex); \ - if (pthread_equal (pthread_self (), main_thread)) \ - UNBLOCK_INPUT; \ - } \ - while (0) - -#else /* ! defined HAVE_PTHREAD */ - -#define BLOCK_INPUT_ALLOC BLOCK_INPUT -#define UNBLOCK_INPUT_ALLOC UNBLOCK_INPUT - -#endif /* ! defined HAVE_PTHREAD */ -#endif /* ! defined SYSTEM_MALLOC && ! defined SYNC_INPUT */ - /* Mark, unmark, query mark bit of a Lisp string. S must be a pointer to a struct Lisp_String. */ @@ -205,10 +145,6 @@ static char *spare_memory[7]; #define SPARE_MEMORY (1 << 14) -/* Number of extra blocks malloc should get when it needs more core. */ - -static int malloc_hysteresis; - /* Initialize it to a nonzero value to force it into data space (rather than bss space). That way unexec will remap it into text space (pure), on some systems. We have not implemented the @@ -413,12 +349,12 @@ static void mark_memory (void *, void *); static void mem_init (void); static struct mem_node *mem_insert (void *, void *, enum mem_type); static void mem_insert_fixup (struct mem_node *); -#endif static void mem_rotate_left (struct mem_node *); static void mem_rotate_right (struct mem_node *); static void mem_delete (struct mem_node *); static void mem_delete_fixup (struct mem_node *); static inline struct mem_node *mem_find (void *); +#endif #if GC_MARK_STACK == GC_MARK_STACK_CHECK_GCPROS @@ -587,39 +523,17 @@ xmalloc_get_size (unsigned char *ptr) } -/* The call depth in overrun_check functions. For example, this might happen: - xmalloc() - overrun_check_malloc() - -> malloc -> (via hook)_-> emacs_blocked_malloc - -> overrun_check_malloc - call malloc (hooks are NULL, so real malloc is called). - malloc returns 10000. - add overhead, return 10016. - <- (back in overrun_check_malloc) - add overhead again, return 10032 - xmalloc returns 10032. - - (time passes). - - xfree(10032) - overrun_check_free(10032) - decrease overhead - free(10016) <- crash, because 10000 is the original pointer. */ - -static ptrdiff_t check_depth; - /* Like malloc, but wraps allocated block with header and trailer. */ static void * overrun_check_malloc (size_t size) { register unsigned char *val; - int overhead = ++check_depth == 1 ? XMALLOC_OVERRUN_CHECK_OVERHEAD : 0; - if (SIZE_MAX - overhead < size) + if (SIZE_MAX - XMALLOC_OVERRUN_CHECK_OVERHEAD < size) emacs_abort (); - val = malloc (size + overhead); - if (val && check_depth == 1) + val = malloc (size + XMALLOC_OVERRUN_CHECK_OVERHEAD); + if (val) { memcpy (val, xmalloc_overrun_check_header, XMALLOC_OVERRUN_CHECK_SIZE); val += XMALLOC_OVERRUN_CHECK_SIZE + XMALLOC_OVERRUN_SIZE_SIZE; @@ -627,7 +541,6 @@ overrun_check_malloc (size_t size) memcpy (val + size, xmalloc_overrun_check_trailer, XMALLOC_OVERRUN_CHECK_SIZE); } - --check_depth; return val; } @@ -639,12 +552,10 @@ static void * overrun_check_realloc (void *block, size_t size) { register unsigned char *val = (unsigned char *) block; - int overhead = ++check_depth == 1 ? XMALLOC_OVERRUN_CHECK_OVERHEAD : 0; - if (SIZE_MAX - overhead < size) + if (SIZE_MAX - XMALLOC_OVERRUN_CHECK_OVERHEAD < size) emacs_abort (); if (val - && check_depth == 1 && memcmp (xmalloc_overrun_check_header, val - XMALLOC_OVERRUN_CHECK_SIZE - XMALLOC_OVERRUN_SIZE_SIZE, XMALLOC_OVERRUN_CHECK_SIZE) == 0) @@ -658,9 +569,9 @@ overrun_check_realloc (void *block, size_t size) memset (val, 0, XMALLOC_OVERRUN_CHECK_SIZE + XMALLOC_OVERRUN_SIZE_SIZE); } - val = realloc (val, size + overhead); + val = realloc (val, size + XMALLOC_OVERRUN_CHECK_OVERHEAD); - if (val && check_depth == 1) + if (val) { memcpy (val, xmalloc_overrun_check_header, XMALLOC_OVERRUN_CHECK_SIZE); val += XMALLOC_OVERRUN_CHECK_SIZE + XMALLOC_OVERRUN_SIZE_SIZE; @@ -668,7 +579,6 @@ overrun_check_realloc (void *block, size_t size) memcpy (val + size, xmalloc_overrun_check_trailer, XMALLOC_OVERRUN_CHECK_SIZE); } - --check_depth; return val; } @@ -679,9 +589,7 @@ overrun_check_free (void *block) { unsigned char *val = (unsigned char *) block; - ++check_depth; if (val - && check_depth == 1 && memcmp (xmalloc_overrun_check_header, val - XMALLOC_OVERRUN_CHECK_SIZE - XMALLOC_OVERRUN_SIZE_SIZE, XMALLOC_OVERRUN_CHECK_SIZE) == 0) @@ -701,7 +609,6 @@ overrun_check_free (void *block) } free (val); - --check_depth; } #undef malloc @@ -712,14 +619,33 @@ overrun_check_free (void *block) #define free overrun_check_free #endif -#ifdef SYNC_INPUT -/* When using SYNC_INPUT, we don't call malloc from a signal handler, so - there's no need to block input around malloc. */ -#define MALLOC_BLOCK_INPUT ((void)0) -#define MALLOC_UNBLOCK_INPUT ((void)0) +/* If compiled with XMALLOC_BLOCK_INPUT_CHECK, define a symbol + BLOCK_INPUT_IN_MEMORY_ALLOCATORS that is visible to the debugger. + If that variable is set, block input while in one of Emacs's memory + allocation functions. There should be no need for this debugging + option, since signal handlers do not allocate memory, but Emacs + formerly allocated memory in signal handlers and this compile-time + option remains as a way to help debug the issue should it rear its + ugly head again. */ +#ifdef XMALLOC_BLOCK_INPUT_CHECK +bool block_input_in_memory_allocators EXTERNALLY_VISIBLE; +static void +malloc_block_input (void) +{ + if (block_input_in_memory_allocators) + BLOCK_INPUT; +} +static void +malloc_unblock_input (void) +{ + if (block_input_in_memory_allocators) + UNBLOCK_INPUT; +} +# define MALLOC_BLOCK_INPUT malloc_block_input () +# define MALLOC_UNBLOCK_INPUT malloc_unblock_input () #else -#define MALLOC_BLOCK_INPUT BLOCK_INPUT -#define MALLOC_UNBLOCK_INPUT UNBLOCK_INPUT +# define MALLOC_BLOCK_INPUT ((void) 0) +# define MALLOC_UNBLOCK_INPUT ((void) 0) #endif /* Like malloc but check for no memory and block interrupt input.. */ @@ -788,8 +714,7 @@ xfree (void *block) free (block); MALLOC_UNBLOCK_INPUT; /* We don't call refill_memory_reserve here - because that duplicates doing so in emacs_blocked_free - and the criterion should go there. */ + because in practice the call in r_alloc_free seems to suffice. */ } @@ -1216,256 +1141,6 @@ lisp_align_free (void *block) } -#ifndef SYSTEM_MALLOC - -/* Arranging to disable input signals while we're in malloc. - - This only works with GNU malloc. To help out systems which can't - use GNU malloc, all the calls to malloc, realloc, and free - elsewhere in the code should be inside a BLOCK_INPUT/UNBLOCK_INPUT - pair; unfortunately, we have no idea what C library functions - might call malloc, so we can't really protect them unless you're - using GNU malloc. Fortunately, most of the major operating systems - can use GNU malloc. */ - -#ifndef SYNC_INPUT -/* When using SYNC_INPUT, we don't call malloc from a signal handler, so - there's no need to block input around malloc. */ - -#ifndef DOUG_LEA_MALLOC -extern void * (*__malloc_hook) (size_t, const void *); -extern void * (*__realloc_hook) (void *, size_t, const void *); -extern void (*__free_hook) (void *, const void *); -/* Else declared in malloc.h, perhaps with an extra arg. */ -#endif /* DOUG_LEA_MALLOC */ -static void * (*old_malloc_hook) (size_t, const void *); -static void * (*old_realloc_hook) (void *, size_t, const void*); -static void (*old_free_hook) (void*, const void*); - -#ifdef DOUG_LEA_MALLOC -# define BYTES_USED (mallinfo ().uordblks) -#else -# define BYTES_USED _bytes_used -#endif - -#ifdef GC_MALLOC_CHECK -static bool dont_register_blocks; -#endif - -static size_t bytes_used_when_reconsidered; - -/* Value of _bytes_used, when spare_memory was freed. */ - -static size_t bytes_used_when_full; - -/* This function is used as the hook for free to call. */ - -static void -emacs_blocked_free (void *ptr, const void *ptr2) -{ - BLOCK_INPUT_ALLOC; - -#ifdef GC_MALLOC_CHECK - if (ptr) - { - struct mem_node *m; - - m = mem_find (ptr); - if (m == MEM_NIL || m->start != ptr) - { - fprintf (stderr, - "Freeing `%p' which wasn't allocated with malloc\n", ptr); - emacs_abort (); - } - else - { - /* fprintf (stderr, "free %p...%p (%p)\n", m->start, m->end, ptr); */ - mem_delete (m); - } - } -#endif /* GC_MALLOC_CHECK */ - - __free_hook = old_free_hook; - free (ptr); - - /* If we released our reserve (due to running out of memory), - and we have a fair amount free once again, - try to set aside another reserve in case we run out once more. */ - if (! NILP (Vmemory_full) - /* Verify there is enough space that even with the malloc - hysteresis this call won't run out again. - The code here is correct as long as SPARE_MEMORY - is substantially larger than the block size malloc uses. */ - && (bytes_used_when_full - > ((bytes_used_when_reconsidered = BYTES_USED) - + max (malloc_hysteresis, 4) * SPARE_MEMORY))) - refill_memory_reserve (); - - __free_hook = emacs_blocked_free; - UNBLOCK_INPUT_ALLOC; -} - - -/* This function is the malloc hook that Emacs uses. */ - -static void * -emacs_blocked_malloc (size_t size, const void *ptr) -{ - void *value; - - BLOCK_INPUT_ALLOC; - __malloc_hook = old_malloc_hook; -#ifdef DOUG_LEA_MALLOC - /* Segfaults on my system. --lorentey */ - /* mallopt (M_TOP_PAD, malloc_hysteresis * 4096); */ -#else - __malloc_extra_blocks = malloc_hysteresis; -#endif - - value = malloc (size); - -#ifdef GC_MALLOC_CHECK - { - struct mem_node *m = mem_find (value); - if (m != MEM_NIL) - { - fprintf (stderr, "Malloc returned %p which is already in use\n", - value); - fprintf (stderr, "Region in use is %p...%p, %td bytes, type %d\n", - m->start, m->end, (char *) m->end - (char *) m->start, - m->type); - emacs_abort (); - } - - if (!dont_register_blocks) - { - mem_insert (value, (char *) value + max (1, size), allocated_mem_type); - allocated_mem_type = MEM_TYPE_NON_LISP; - } - } -#endif /* GC_MALLOC_CHECK */ - - __malloc_hook = emacs_blocked_malloc; - UNBLOCK_INPUT_ALLOC; - - /* fprintf (stderr, "%p malloc\n", value); */ - return value; -} - - -/* This function is the realloc hook that Emacs uses. */ - -static void * -emacs_blocked_realloc (void *ptr, size_t size, const void *ptr2) -{ - void *value; - - BLOCK_INPUT_ALLOC; - __realloc_hook = old_realloc_hook; - -#ifdef GC_MALLOC_CHECK - if (ptr) - { - struct mem_node *m = mem_find (ptr); - if (m == MEM_NIL || m->start != ptr) - { - fprintf (stderr, - "Realloc of %p which wasn't allocated with malloc\n", - ptr); - emacs_abort (); - } - - mem_delete (m); - } - - /* fprintf (stderr, "%p -> realloc\n", ptr); */ - - /* Prevent malloc from registering blocks. */ - dont_register_blocks = 1; -#endif /* GC_MALLOC_CHECK */ - - value = realloc (ptr, size); - -#ifdef GC_MALLOC_CHECK - dont_register_blocks = 0; - - { - struct mem_node *m = mem_find (value); - if (m != MEM_NIL) - { - fprintf (stderr, "Realloc returns memory that is already in use\n"); - emacs_abort (); - } - - /* Can't handle zero size regions in the red-black tree. */ - mem_insert (value, (char *) value + max (size, 1), MEM_TYPE_NON_LISP); - } - - /* fprintf (stderr, "%p <- realloc\n", value); */ -#endif /* GC_MALLOC_CHECK */ - - __realloc_hook = emacs_blocked_realloc; - UNBLOCK_INPUT_ALLOC; - - return value; -} - - -#ifdef HAVE_PTHREAD -/* Called from Fdump_emacs so that when the dumped Emacs starts, it has a - normal malloc. Some thread implementations need this as they call - malloc before main. The pthread_self call in BLOCK_INPUT_ALLOC then - calls malloc because it is the first call, and we have an endless loop. */ - -void -reset_malloc_hooks (void) -{ - __free_hook = old_free_hook; - __malloc_hook = old_malloc_hook; - __realloc_hook = old_realloc_hook; -} -#endif /* HAVE_PTHREAD */ - - -/* Called from main to set up malloc to use our hooks. */ - -void -uninterrupt_malloc (void) -{ -#ifdef HAVE_PTHREAD -#ifdef DOUG_LEA_MALLOC - pthread_mutexattr_t attr; - - /* GLIBC has a faster way to do this, but let's keep it portable. - This is according to the Single UNIX Specification. */ - pthread_mutexattr_init (&attr); - pthread_mutexattr_settype (&attr, PTHREAD_MUTEX_RECURSIVE); - pthread_mutex_init (&alloc_mutex, &attr); -#else /* !DOUG_LEA_MALLOC */ - /* Some systems such as Solaris 2.6 don't have a recursive mutex, - and the bundled gmalloc.c doesn't require it. */ - pthread_mutex_init (&alloc_mutex, NULL); -#endif /* !DOUG_LEA_MALLOC */ -#endif /* HAVE_PTHREAD */ - - if (__free_hook != emacs_blocked_free) - old_free_hook = __free_hook; - __free_hook = emacs_blocked_free; - - if (__malloc_hook != emacs_blocked_malloc) - old_malloc_hook = __malloc_hook; - __malloc_hook = emacs_blocked_malloc; - - if (__realloc_hook != emacs_blocked_realloc) - old_realloc_hook = __realloc_hook; - __realloc_hook = emacs_blocked_realloc; -} - -#endif /* not SYNC_INPUT */ -#endif /* not SYSTEM_MALLOC */ - - - /*********************************************************************** Interval Allocation ***********************************************************************/ @@ -1511,8 +1186,6 @@ make_interval (void) { INTERVAL val; - /* eassert (!handling_signal); */ - MALLOC_BLOCK_INPUT; if (interval_free_list) @@ -1896,8 +1569,6 @@ allocate_string (void) { struct Lisp_String *s; - /* eassert (!handling_signal); */ - MALLOC_BLOCK_INPUT; /* If the free-list is empty, allocate a new string_block, and @@ -2589,8 +2260,6 @@ make_float (double float_value) { register Lisp_Object val; - /* eassert (!handling_signal); */ - MALLOC_BLOCK_INPUT; if (float_free_list) @@ -2698,8 +2367,6 @@ DEFUN ("cons", Fcons, Scons, 2, 2, 0, { register Lisp_Object val; - /* eassert (!handling_signal); */ - MALLOC_BLOCK_INPUT; if (cons_free_list) @@ -3205,9 +2872,6 @@ allocate_vectorlike (ptrdiff_t len) MALLOC_BLOCK_INPUT; - /* This gets triggered by code which I haven't bothered to fix. --Stef */ - /* eassert (!handling_signal); */ - if (len == 0) p = XVECTOR (zero_vector); else @@ -3492,8 +3156,6 @@ Its value and function definition are void, and its property list is nil. */) CHECK_STRING (name); - /* eassert (!handling_signal); */ - MALLOC_BLOCK_INPUT; if (symbol_free_list) @@ -3578,8 +3240,6 @@ allocate_misc (enum Lisp_Misc_Type type) { Lisp_Object val; - /* eassert (!handling_signal); */ - MALLOC_BLOCK_INPUT; if (marker_free_list) @@ -3799,12 +3459,6 @@ memory_full (size_t nbytes) lisp_free (spare_memory[i]); spare_memory[i] = 0; } - - /* Record the space now used. When it decreases substantially, - we can refill the memory reserve. */ -#if !defined SYSTEM_MALLOC && !defined SYNC_INPUT - bytes_used_when_full = BYTES_USED; -#endif } /* 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) /* Create a new node. */ #ifdef GC_MALLOC_CHECK - x = _malloc_internal (sizeof *x); + x = malloc (sizeof *x); if (x == NULL) emacs_abort (); #else @@ -4166,7 +3820,7 @@ mem_delete (struct mem_node *z) mem_delete_fixup (x); #ifdef GC_MALLOC_CHECK - _free_internal (y); + free (y); #else xfree (y); #endif @@ -6767,12 +6421,6 @@ init_alloc_once (void) init_strings (); init_vectors (); -#ifdef REL_ALLOC - malloc_hysteresis = 32; -#else - malloc_hysteresis = 0; -#endif - refill_memory_reserve (); gc_cons_threshold = GC_DEFAULT_THRESHOLD; } diff --git a/src/atimer.c b/src/atimer.c index 80b813fe4f..5dbd807872 100644 --- a/src/atimer.c +++ b/src/atimer.c @@ -369,7 +369,6 @@ run_timers (void) if (! atimers) pending_atimers = 0; -#ifdef SYNC_INPUT if (pending_atimers) pending_signals = 1; else @@ -377,10 +376,6 @@ run_timers (void) pending_signals = interrupt_input_pending; set_alarm (); } -#else - if (! pending_atimers) - set_alarm (); -#endif } @@ -391,11 +386,7 @@ static void handle_alarm_signal (int sig) { pending_atimers = 1; -#ifdef SYNC_INPUT pending_signals = 1; -#else - run_timers (); -#endif } static void diff --git a/src/bytecode.c b/src/bytecode.c index b151078f60..5f4fdcc5ef 100644 --- a/src/bytecode.c +++ b/src/bytecode.c @@ -458,7 +458,8 @@ unmark_byte_stack (void) Fsignal (Qquit, Qnil); \ AFTER_POTENTIAL_GC (); \ } \ - ELSE_PENDING_SIGNALS \ + else if (pending_signals) \ + process_pending_signals (); \ } while (0) diff --git a/src/conf_post.h b/src/conf_post.h index 94934ffead..0c4d029bc5 100644 --- a/src/conf_post.h +++ b/src/conf_post.h @@ -90,7 +90,6 @@ along with GNU Emacs. If not, see . */ char *_getpty(); #endif -#undef SA_RESTART /* not the same as defining BROKEN_SA_RESTART */ #endif /* IRIX6_5 */ #ifdef MSDOS diff --git a/src/emacs.c b/src/emacs.c index 1416bf76c4..233c0e68a1 100644 --- a/src/emacs.c +++ b/src/emacs.c @@ -848,14 +848,10 @@ main (int argc, char **argv) /* Arrange to get warning messages as memory fills up. */ memory_warnings (0, malloc_warning); - /* Call malloc at least once, to run the initial __malloc_hook. + /* Call malloc at least once, to run malloc_initialize_hook. Also call realloc and free for consistency. */ free (realloc (malloc (4), 4)); -# ifndef SYNC_INPUT - /* Arrange to disable interrupt input inside malloc etc. */ - uninterrupt_malloc (); -# endif /* not SYNC_INPUT */ #endif /* not SYSTEM_MALLOC */ #if defined (MSDOS) || defined (WINDOWSNT) @@ -2143,12 +2139,6 @@ You must run Emacs in batch mode in order to dump it. */) memory_warnings (my_edata, malloc_warning); } #endif /* not WINDOWSNT */ -#if defined (HAVE_PTHREAD) && !defined SYNC_INPUT - /* Pthread may call malloc before main, and then we will get an endless - loop, because pthread_self (see alloc.c) calls malloc the first time - it is called on some systems. */ - reset_malloc_hooks (); -#endif #endif /* not SYSTEM_MALLOC */ #ifdef DOUG_LEA_MALLOC malloc_state_ptr = malloc_get_state (); diff --git a/src/eval.c b/src/eval.c index 6cca13a8fd..1c565e233c 100644 --- a/src/eval.c +++ b/src/eval.c @@ -117,12 +117,6 @@ static EMACS_INT when_entered_debugger; Lisp_Object Vsignaling_function; -/* Set to non-zero while processing X events. Checked in Feval to - make sure the Lisp interpreter isn't called from a signal handler, - which is unsafe because the interpreter isn't reentrant. */ - -int handling_signal; - /* If non-nil, Lisp code must not be run since some part of Emacs is in an inconsistent state. Currently, x-create-frame uses this to avoid triggering window-configuration-change-hook while the new @@ -1106,7 +1100,6 @@ unwind_to_catch (struct catchtag *catch, Lisp_Object value) /* Restore certain special C variables. */ set_poll_suppress_count (catch->poll_suppress_count); UNBLOCK_INPUT_TO (catch->interrupt_input_blocked); - handling_signal = 0; immediate_quit = 0; do @@ -1486,7 +1479,7 @@ See also the function `condition-case'. */) struct handler *h; struct backtrace *bp; - immediate_quit = handling_signal = 0; + immediate_quit = 0; abort_on_gc = 0; if (gc_in_progress || waiting_for_input) emacs_abort (); @@ -2039,9 +2032,6 @@ eval_sub (Lisp_Object form) struct backtrace backtrace; struct gcpro gcpro1, gcpro2, gcpro3; - if (handling_signal) - emacs_abort (); - if (SYMBOLP (form)) { /* Look up its binding in the lexical environment. @@ -3104,8 +3094,6 @@ specbind (Lisp_Object symbol, Lisp_Object value) { struct Lisp_Symbol *sym; - eassert (!handling_signal); - CHECK_SYMBOL (symbol); sym = XSYMBOL (symbol); if (specpdl_ptr == specpdl + specpdl_size) @@ -3199,8 +3187,6 @@ specbind (Lisp_Object symbol, Lisp_Object value) void record_unwind_protect (Lisp_Object (*function) (Lisp_Object), Lisp_Object arg) { - eassert (!handling_signal); - if (specpdl_ptr == specpdl + specpdl_size) grow_specpdl (); specpdl_ptr->func = function; diff --git a/src/intervals.c b/src/intervals.c index 5a47cacb2d..584ee1e923 100644 --- a/src/intervals.c +++ b/src/intervals.c @@ -673,8 +673,7 @@ find_interval (register INTERVAL tree, register ptrdiff_t position) eassert (relative_position <= TOTAL_LENGTH (tree)); - if (!handling_signal) - tree = balance_possible_root_interval (tree); + tree = balance_possible_root_interval (tree); while (1) { diff --git a/src/keyboard.c b/src/keyboard.c index d164083fb8..01644b3832 100644 --- a/src/keyboard.c +++ b/src/keyboard.c @@ -84,9 +84,7 @@ int interrupt_input_pending; pending_atimers separately, to reduce code size. So, any code that changes interrupt_input_pending or pending_atimers should update this too. */ -#ifdef SYNC_INPUT int pending_signals; -#endif #define KBD_BUFFER_SIZE 4096 @@ -2010,17 +2008,9 @@ static struct atimer *poll_timer; void poll_for_input_1 (void) { -/* Tell ns_read_socket() it is being called asynchronously so it can avoid - doing anything dangerous. */ -#ifdef HAVE_NS - ++handling_signal; -#endif if (interrupt_input_blocked == 0 && !waiting_for_input) read_avail_input (0); -#ifdef HAVE_NS - --handling_signal; -#endif } /* Timer callback function for poll_timer. TIMER is equal to @@ -2031,12 +2021,8 @@ poll_for_input (struct atimer *timer) { if (poll_suppress_count == 0) { -#ifdef SYNC_INPUT interrupt_input_pending = 1; pending_signals = 1; -#else - poll_for_input_1 (); -#endif } } @@ -7176,19 +7162,12 @@ tty_read_avail_input (struct terminal *terminal, return nread; } -#if defined SYNC_INPUT || defined USABLE_SIGIO static void handle_async_input (void) { interrupt_input_pending = 0; -#ifdef SYNC_INPUT pending_signals = pending_atimers; -#endif -/* Tell ns_read_socket() it is being called asynchronously so it can avoid - doing anything dangerous. */ -#ifdef HAVE_NS - ++handling_signal; -#endif + while (1) { int nread; @@ -7199,13 +7178,8 @@ handle_async_input (void) if (nread <= 0) break; } -#ifdef HAVE_NS - --handling_signal; -#endif } -#endif /* SYNC_INPUT || USABLE_SIGIO */ -#ifdef SYNC_INPUT void process_pending_signals (void) { @@ -7213,24 +7187,17 @@ process_pending_signals (void) handle_async_input (); do_pending_atimers (); } -#endif #ifdef USABLE_SIGIO static void handle_input_available_signal (int sig) { -#ifdef SYNC_INPUT interrupt_input_pending = 1; pending_signals = 1; -#endif if (input_available_clear_time) *input_available_clear_time = make_emacs_time (0, 0); - -#ifndef SYNC_INPUT - handle_async_input (); -#endif } static void @@ -11365,9 +11332,7 @@ init_keyboard (void) input_pending = 0; interrupt_input_blocked = 0; interrupt_input_pending = 0; -#ifdef SYNC_INPUT pending_signals = 0; -#endif /* This means that command_loop_1 won't try to select anything the first time through. */ diff --git a/src/lisp.h b/src/lisp.h index 447c6bd296..3a473a60b4 100644 --- a/src/lisp.h +++ b/src/lisp.h @@ -2107,22 +2107,16 @@ extern char *stack_bottom; If quit-flag is set to `kill-emacs' the SIGINT handler has received a request to exit Emacs when it is safe to do. */ -#ifdef SYNC_INPUT extern void process_pending_signals (void); extern int pending_signals; -#define ELSE_PENDING_SIGNALS \ - else if (pending_signals) \ - process_pending_signals (); -#else /* not SYNC_INPUT */ -#define ELSE_PENDING_SIGNALS -#endif /* not SYNC_INPUT */ extern void process_quit_flag (void); #define QUIT \ do { \ if (!NILP (Vquit_flag) && NILP (Vinhibit_quit)) \ process_quit_flag (); \ - ELSE_PENDING_SIGNALS \ + else if (pending_signals) \ + process_pending_signals (); \ } while (0) @@ -2846,8 +2840,6 @@ extern void memory_warnings (void *, void (*warnfun) (const char *)); /* Defined in alloc.c. */ extern void check_pure_size (void); extern void allocate_string_data (struct Lisp_String *, EMACS_INT, EMACS_INT); -extern void reset_malloc_hooks (void); -extern void uninterrupt_malloc (void); extern void malloc_warning (const char *); extern _Noreturn void memory_full (size_t); extern _Noreturn void buffer_memory_full (ptrdiff_t); @@ -3043,7 +3035,6 @@ extern Lisp_Object Qand_rest; extern Lisp_Object Vautoload_queue; extern Lisp_Object Vsignaling_function; extern Lisp_Object inhibit_lisp_code; -extern int handling_signal; #if BYTE_MARK_STACK extern struct catchtag *catchlist; extern struct handler *handlerlist; diff --git a/src/nsmenu.m b/src/nsmenu.m index 3057f4f6a2..907d3eac62 100644 --- a/src/nsmenu.m +++ b/src/nsmenu.m @@ -588,10 +588,7 @@ extern NSString *NSMenuDidBeginTrackingNotification; From 10.6 on, we could also use -[NSMenu propertiesToUpdate]: In the key press case, NSMenuPropertyItemImage (e.g.) won't be set. */ - if (trackingMenu == 0 - /* Also, don't try this if from an event picked up asynchronously, - as lots of lisp evaluation happens in ns_update_menubar. */ - || handling_signal != 0) + if (trackingMenu == 0) return; /*fprintf (stderr, "Updating menu '%s'\n", [[self title] UTF8String]); NSLog (@"%@\n", event); */ ns_update_menubar (frame, 1, self); diff --git a/src/nsterm.m b/src/nsterm.m index 41520ce74d..0b26508dbd 100644 --- a/src/nsterm.m +++ b/src/nsterm.m @@ -3355,16 +3355,12 @@ ns_read_socket (struct terminal *terminal, int expected, if (interrupt_input_blocked) { interrupt_input_pending = 1; -#ifdef SYNC_INPUT pending_signals = 1; -#endif return -1; } interrupt_input_pending = 0; -#ifdef SYNC_INPUT pending_signals = pending_atimers; -#endif BLOCK_INPUT; n_emacs_events_pending = 0; @@ -3726,7 +3722,7 @@ ns_judge_scroll_bars (struct frame *f) removed = YES; } - if (removed) + if (removed) [eview updateFrameSize: NO]; } @@ -3988,7 +3984,6 @@ ns_term_init (Lisp_Object display_name) /* count object allocs (About, click icon); on OS X use ObjectAlloc tool */ /*GSDebugAllocationActive (YES); */ BLOCK_INPUT; - handling_signal = 0; baud_rate = 38400; Fset_input_interrupt_mode (Qnil); @@ -6239,7 +6234,7 @@ not_in_argv (NSString *arg) NSRect r = [super constrainFrameRect:frameRect toScreen:screen]; return r; } - + if (f->output_data.ns->dont_constrain || ns_menu_bar_should_be_hidden ()) return frameRect; diff --git a/src/process.c b/src/process.c index 6dbff6f4b1..a371dece25 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, Otherwise, do pending quit if requested. */ if (read_kbd >= 0) QUIT; -#ifdef SYNC_INPUT else process_pending_signals (); -#endif /* Exit now if the cell we're waiting for became non-nil. */ if (! NILP (wait_for_cell) && ! NILP (XCAR (wait_for_cell))) diff --git a/src/regex.c b/src/regex.c index 92264ccae2..17562043df 100644 --- a/src/regex.c +++ b/src/regex.c @@ -1831,9 +1831,9 @@ typedef struct /* The next available element. */ #define COMPILE_STACK_TOP (compile_stack.stack[compile_stack.avail]) -/* Explicit quit checking is only used on NTemacs and whenever we - use polling to process input events. */ -#if defined emacs && (defined WINDOWSNT || defined SYNC_INPUT) && defined QUIT +/* Explicit quit checking is needed for Emacs, which uses polling to + process input events. */ +#ifdef emacs extern int immediate_quit; # define IMMEDIATE_QUIT_CHECK \ do { \ diff --git a/src/sysdep.c b/src/sysdep.c index 9065b38d6f..dbfd9efc7d 100644 --- a/src/sysdep.c +++ b/src/sysdep.c @@ -1447,27 +1447,21 @@ emacs_sigaction_init (struct sigaction *action, signal_handler_t handler) action->sa_handler = handler; action->sa_flags = 0; #if defined (SA_RESTART) - /* Emacs mostly works better with restartable system services. If this - flag exists, we probably want to turn it on here. - However, on some systems (only hpux11 at present) this resets the - timeout of `select' which means that `select' never finishes if - it keeps getting signals. - We define BROKEN_SA_RESTART on those systems. */ - /* It's not clear why the comment above says "mostly works better". --Stef - When SYNC_INPUT is set, we don't want SA_RESTART because we need to poll + /* SA_RESTART causes interruptible functions with timeouts (e.g., + 'select') to reset their timeout on some platforms (e.g., + HP-UX 11), which is not what we want. Also, when Emacs is + interactive, we don't want SA_RESTART because we need to poll for pending input so we need long-running syscalls to be interrupted after a signal that sets the interrupt_input_pending flag. */ /* Non-interactive keyboard input goes through stdio, where we always want restartable system calls. */ -# if defined (BROKEN_SA_RESTART) || defined (SYNC_INPUT) if (noninteractive) -# endif action->sa_flags = SA_RESTART; #endif } #ifdef FORWARD_SIGNAL_TO_MAIN_THREAD -pthread_t main_thread; +static pthread_t main_thread; #endif /* 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) { if (errno == EINTR) { -#ifdef SYNC_INPUT /* I originally used `QUIT' but that might causes files to be truncated if you hit C-g in the middle of it. --Stef */ process_pending_signals (); -#endif continue; } else diff --git a/src/syssignal.h b/src/syssignal.h index 5e733dd812..e309e6725b 100644 --- a/src/syssignal.h +++ b/src/syssignal.h @@ -64,8 +64,4 @@ extern void emacs_sigaction_init (struct sigaction *, signal_handler_t); char *strsignal (int); #endif -#ifdef FORWARD_SIGNAL_TO_MAIN_THREAD -extern pthread_t main_thread; -#endif - void handle_on_main_thread (int, signal_handler_t); diff --git a/src/xdisp.c b/src/xdisp.c index 8e0975cf65..5ee5a46601 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) struct gcpro gcpro1, gcpro2, gcpro3, gcpro4; USE_SAFE_ALLOCA; - /* Do nothing if called asynchronously. Inserting text into - a buffer may call after-change-functions and alike and - that would means running Lisp asynchronously. */ - if (handling_signal) - return; - fmt = msg = Qnil; GCPRO4 (fmt, msg, arg1, arg2); diff --git a/src/xterm.c b/src/xterm.c index 900a1d78b8..9ab53dc087 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -7129,25 +7129,17 @@ XTread_socket (struct terminal *terminal, int expected, struct input_event *hold if (interrupt_input_blocked) { interrupt_input_pending = 1; -#ifdef SYNC_INPUT pending_signals = 1; -#endif return -1; } interrupt_input_pending = 0; -#ifdef SYNC_INPUT pending_signals = pending_atimers; -#endif BLOCK_INPUT; /* So people can tell when we have read the available input. */ input_signal_count++; -#ifndef SYNC_INPUT - ++handling_signal; -#endif - /* For debugging, this gives a way to fake an I/O error. */ if (terminal->display_info.x == XTread_socket_fake_io_error) { @@ -7236,9 +7228,6 @@ XTread_socket (struct terminal *terminal, int expected, struct input_event *hold pending_autoraise_frame = 0; } -#ifndef SYNC_INPUT - --handling_signal; -#endif UNBLOCK_INPUT; return count; @@ -7788,7 +7777,6 @@ x_connection_closed (Display *dpy, const char *error_message) error_msg = alloca (strlen (error_message) + 1); strcpy (error_msg, error_message); - handling_signal = 0; /* Inhibit redisplay while frames are being deleted. */ specbind (Qinhibit_redisplay, Qt); -- 2.20.1