summaryrefslogtreecommitdiff
path: root/src/alloc.c
diff options
context:
space:
mode:
authorJan Djärv <jan.h.d@swipnet.se>2004-12-07 08:25:43 +0000
committerJan Djärv <jan.h.d@swipnet.se>2004-12-07 08:25:43 +0000
commitbf2e332bd196db7148d2150cc24b32dd9b4a045e (patch)
treed7b5160018459fc648b61a39cfcd26f4116f048a /src/alloc.c
parent521d7320124a07fd6df2ca6c225bcd3947c89367 (diff)
downloademacs-bf2e332bd196db7148d2150cc24b32dd9b4a045e.tar.gz
* gtkutil.c: Include signal.h and syssignal.h.
(xg_get_file_name): Block and unblock __SIGRTMIN if defined. * alloc.c: If HAVE_GTK_AND_PTHREAD, include pthread.h, new variables main_thread and alloc_mutex, define (UN)BLOCK_INPUT_ALLOC to use alloc_mutex to protect emacs_blocked_* calls and only do (UN)BLOCK_INPUT in the main thread. If not HAVE_GTK_AND_PTHREAD, (UN)BLOCK_INPUT_ALLOC is the same as (UN)BLOCK_INPUT. (emacs_blocked_free, emacs_blocked_malloc) (emacs_blocked_realloc): Use (UN)BLOCK_INPUT_ALLOC. (uninterrupt_malloc): Initialize main_thread and alloc_mutex. (reset_malloc_hooks): New function. * lisp.h: Declare reset_malloc_hooks. * emacs.c (Fdump_emacs): Call reset_malloc_hooks. * keyboard.c: Conditionally include pthread.h (handle_async_inpu, input_available_signalt): If not in the main thread, block signal, send signal to main thread and return.
Diffstat (limited to 'src/alloc.c')
-rw-r--r--src/alloc.c73
1 files changed, 67 insertions, 6 deletions
diff --git a/src/alloc.c b/src/alloc.c
index e0c14e8bb9c..4f3a0d6f2c4 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -31,6 +31,10 @@ Boston, MA 02111-1307, USA. */
#include <signal.h>
+#ifdef HAVE_GTK_AND_PTHREAD
+#include <pthread.h>
+#endif
+
/* This file is part of the core Lisp implementation, and thus must
deal with the real data structures. If the Lisp implementation is
replaced, this file likely will not be used. */
@@ -85,6 +89,35 @@ extern __malloc_size_t __malloc_extra_blocks;
#endif /* not DOUG_LEA_MALLOC */
+#if ! defined (SYSTEM_MALLOC) && defined (HAVE_GTK_AND_PTHREAD)
+
+static pthread_mutex_t alloc_mutex;
+pthread_t main_thread;
+
+#define BLOCK_INPUT_ALLOC \
+ do \
+ { \
+ pthread_mutex_lock (&alloc_mutex); \
+ if (pthread_self () == main_thread) \
+ BLOCK_INPUT; \
+ } \
+ while (0)
+#define UNBLOCK_INPUT_ALLOC \
+ do \
+ { \
+ if (pthread_self () == main_thread) \
+ UNBLOCK_INPUT; \
+ pthread_mutex_unlock (&alloc_mutex); \
+ } \
+ while (0)
+
+#else /* SYSTEM_MALLOC || not HAVE_GTK_AND_PTHREAD */
+
+#define BLOCK_INPUT_ALLOC BLOCK_INPUT
+#define UNBLOCK_INPUT_ALLOC UNBLOCK_INPUT
+
+#endif /* SYSTEM_MALLOC || not HAVE_GTK_AND_PTHREAD */
+
/* Value of _bytes_used, when spare_memory was freed. */
static __malloc_size_t bytes_used_when_full;
@@ -1068,7 +1101,7 @@ static void
emacs_blocked_free (ptr)
void *ptr;
{
- BLOCK_INPUT;
+ BLOCK_INPUT_ALLOC;
#ifdef GC_MALLOC_CHECK
if (ptr)
@@ -1106,7 +1139,7 @@ emacs_blocked_free (ptr)
spare_memory = (char *) malloc ((size_t) SPARE_MEMORY);
__free_hook = emacs_blocked_free;
- UNBLOCK_INPUT;
+ UNBLOCK_INPUT_ALLOC;
}
@@ -1132,7 +1165,7 @@ emacs_blocked_malloc (size)
{
void *value;
- BLOCK_INPUT;
+ BLOCK_INPUT_ALLOC;
__malloc_hook = old_malloc_hook;
#ifdef DOUG_LEA_MALLOC
mallopt (M_TOP_PAD, malloc_hysteresis * 4096);
@@ -1164,7 +1197,7 @@ emacs_blocked_malloc (size)
#endif /* GC_MALLOC_CHECK */
__malloc_hook = emacs_blocked_malloc;
- UNBLOCK_INPUT;
+ UNBLOCK_INPUT_ALLOC;
/* fprintf (stderr, "%p malloc\n", value); */
return value;
@@ -1180,7 +1213,7 @@ emacs_blocked_realloc (ptr, size)
{
void *value;
- BLOCK_INPUT;
+ BLOCK_INPUT_ALLOC;
__realloc_hook = old_realloc_hook;
#ifdef GC_MALLOC_CHECK
@@ -1225,17 +1258,45 @@ emacs_blocked_realloc (ptr, size)
#endif /* GC_MALLOC_CHECK */
__realloc_hook = emacs_blocked_realloc;
- UNBLOCK_INPUT;
+ UNBLOCK_INPUT_ALLOC;
return value;
}
+#ifdef HAVE_GTK_AND_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 ()
+{
+ __free_hook = 0;
+ __malloc_hook = 0;
+ __realloc_hook = 0;
+}
+#endif /* HAVE_GTK_AND_PTHREAD */
+
+
/* Called from main to set up malloc to use our hooks. */
void
uninterrupt_malloc ()
{
+#ifdef HAVE_GTK_AND_PTHREAD
+ pthread_mutexattr_t attr;
+
+ /* GLIBC has a faster way to do this, but lets 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);
+
+ main_thread = pthread_self ();
+#endif /* HAVE_GTK_AND_PTHREAD */
+
if (__free_hook != emacs_blocked_free)
old_free_hook = __free_hook;
__free_hook = emacs_blocked_free;