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
This commit is contained in:
parent
634b8cacd6
commit
0caaedb1c3
24 changed files with 113 additions and 544 deletions
|
@ -1,3 +1,8 @@
|
|||
2012-09-16 Paul Eggert <eggert@cs.ucla.edu>
|
||||
|
||||
Remove configure's --without-sync-input option (Bug#12450).
|
||||
* configure.ac (SYNC_INPUT, BROKEN_SA_RESTART): Remove.
|
||||
|
||||
2012-09-16 Glenn Morris <rgm@gnu.org>
|
||||
|
||||
Increase compartmentalization of Nextstep builds rules,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
2012-09-16 Paul Eggert <eggert@cs.ucla.edu>
|
||||
|
||||
Remove configure's --without-sync-input option (Bug#12450).
|
||||
* CPP-DEFINES (BROKEN_SA_RESTART, SA_RESTART): Remove.
|
||||
|
||||
2012-09-16 Glenn Morris <rgm@gnu.org>
|
||||
|
||||
* admin.el (set-version): No more need to set nextstep versions.
|
||||
|
|
10
configure.ac
10
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
|
||||
|
|
|
@ -1,3 +1,9 @@
|
|||
2012-09-16 Paul Eggert <eggert@cs.ucla.edu>
|
||||
|
||||
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 <eggert@cs.ucla.edu>
|
||||
|
||||
Use a more backwards-compatible timer format (Bug#12430).
|
||||
|
|
7
etc/TODO
7
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
|
||||
|
|
|
@ -1,5 +1,47 @@
|
|||
2012-09-16 Paul Eggert <eggert@cs.ucla.edu>
|
||||
|
||||
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 <http://bugs.gnu.org/11080#16>.
|
||||
* 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 <rgm@gnu.org>
|
||||
|
|
424
src/alloc.c
424
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. */
|
||||
}
|
||||
|
||||
|
||||
|
@ -1215,256 +1140,6 @@ lisp_align_free (void *block)
|
|||
MALLOC_UNBLOCK_INPUT;
|
||||
}
|
||||
|
||||
|
||||
#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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
||||
|
|
|
@ -90,7 +90,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
|
|||
char *_getpty();
|
||||
#endif
|
||||
|
||||
#undef SA_RESTART /* not the same as defining BROKEN_SA_RESTART */
|
||||
#endif /* IRIX6_5 */
|
||||
|
||||
#ifdef MSDOS
|
||||
|
|
12
src/emacs.c
12
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 ();
|
||||
|
|
16
src/eval.c
16
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;
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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. */
|
||||
|
|
13
src/lisp.h
13
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;
|
||||
|
|
|
@ -588,10 +588,7 @@ - (void)menuNeedsUpdate: (NSMenu *)menu
|
|||
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);
|
||||
|
|
|
@ -3355,16 +3355,12 @@ overwriting cursor (usually when cursor on a tab) */
|
|||
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 @@ overwriting cursor (usually when cursor on a tab) */
|
|||
removed = YES;
|
||||
}
|
||||
|
||||
if (removed)
|
||||
if (removed)
|
||||
[eview updateFrameSize: NO];
|
||||
}
|
||||
|
||||
|
@ -3988,7 +3984,6 @@ static Lisp_Object ns_string_to_lispmod (const char *s)
|
|||
/* 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 @@ - (NSRect)constrainFrameRect:(NSRect)frameRect toScreen:(NSScreen *)screen
|
|||
NSRect r = [super constrainFrameRect:frameRect toScreen:screen];
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
if (f->output_data.ns->dont_constrain
|
||||
|| ns_menu_bar_should_be_hidden ())
|
||||
return frameRect;
|
||||
|
|
|
@ -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)))
|
||||
|
|
|
@ -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 { \
|
||||
|
|
18
src/sysdep.c
18
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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
12
src/xterm.c
12
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);
|
||||
|
|
Loading…
Add table
Reference in a new issue