diff options
author | Michael Gran <spk121@yahoo.com> | 2017-04-04 08:03:33 -0700 |
---|---|---|
committer | Michael Gran <spk121@yahoo.com> | 2017-04-04 08:03:33 -0700 |
commit | 193bda2b442988e926b478e6bdb09b5d1d75d422 (patch) | |
tree | 6b267f06b2db8fe0c3f43ead6d14d08381a56eee | |
parent | 762dc83006f4677f125de78becf1144a9c16180b (diff) | |
download | guile-193bda2b442988e926b478e6bdb09b5d1d75d422.tar.gz |
prefer producer/consumer to pipes on Cygwin
* libguile/finalizers.c (produce_sem, consume_sem, finalization_data_lock) [SEMAPHORE]: new static vars
(notify_finalizers, notify_forking) [SEMAPHORE]: new static variables
(notify_finalizers_to_run) [SEMAPHORE]: use producer/consumer pattern
(notify_about_to_fork) [SEMAPHORE]: use producer/consumer pattern
(read_finalization_pipe_data) [SEMAPHORE]: use producer/consumer pattern
(scm_set_automatic_finalization_enabled) [SEMAPHORE]: init new static vars
(scm_init_finalizer_thread) [SEMAPHORE]: init new static vars
* libguile/scmsigs.c (produce_sem, consume_sem, signal_data_lock, notify_signal): new static vars
(take_signal) [SEMAPHORE]: use new vars
(read_signal_pipe_data) [SEMAPHORE]: use new vars
(start_signal_delivery_thread) [SEMAPHORE]: init new vars
(scm_i_close_signal_pipe) [SEMAPHORE]: destroy new vars
-rw-r--r-- | libguile/finalizers.c | 104 | ||||
-rw-r--r-- | libguile/scmsigs.c | 60 |
2 files changed, 148 insertions, 16 deletions
diff --git a/libguile/finalizers.c b/libguile/finalizers.c index c5d69e8e3..36be6c3e7 100644 --- a/libguile/finalizers.c +++ b/libguile/finalizers.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2012, 2013, 2014 Free Software Foundation, Inc. +/* Copyright (C) 2012, 2013, 2014, 2017 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License @@ -28,6 +28,11 @@ #include <full-write.h> +#ifdef __CYGWIN__ +#define SEMAPHORE 1 +#include <semaphore.h> +#endif + #include "libguile/bdw-gc.h" #include "libguile/_scm.h" #include "libguile/finalizers.h" @@ -163,8 +168,16 @@ queue_finalizer_async (void) #if SCM_USE_PTHREAD_THREADS - +#if SEMAPHORE +static sem_t produce_sem; +static sem_t consume_sem; +static scm_i_pthread_mutex_t finalization_data_lock = + SCM_I_PTHREAD_MUTEX_INITIALIZER; +static int notify_finalizers = 0; +static int notify_forking = 0; +#else /* ! SEMAPHORE */ static int finalization_pipe[2]; +#endif /* ! SEMAPHORE */ static scm_i_pthread_mutex_t finalization_thread_lock = SCM_I_PTHREAD_MUTEX_INITIALIZER; static pthread_t finalization_thread; @@ -173,15 +186,43 @@ static int finalization_thread_is_running = 0; static void notify_finalizers_to_run (void) { +#if SEMAPHORE + int posted = 0; + sem_wait (&consume_sem); + scm_i_pthread_mutex_lock (&finalization_data_lock); + if (notify_finalizers == 0) + { + notify_finalizers = 1; + posted = 1; + } + scm_i_pthread_mutex_unlock (&finalization_data_lock); + if (posted) + sem_post (&produce_sem); +#else /* ! SEMAPHORE */ char byte = 0; full_write (finalization_pipe[1], &byte, 1); +#endif /* ! SEMAPHORE */ } static void notify_about_to_fork (void) { +#if SEMAPHORE + int posted = 0; + sem_wait (&consume_sem); + scm_i_pthread_mutex_lock (&finalization_data_lock); + if (notify_forking == 0) + { + notify_forking = 1; + posted = 1; + } + scm_i_pthread_mutex_unlock (&finalization_data_lock); + if (posted) + sem_post (&produce_sem); +#else /* ! SEMAPHORE */ char byte = 1; full_write (finalization_pipe[1], &byte, 1); +#endif /* ! SEMAPHORE */ } struct finalization_pipe_data @@ -195,13 +236,37 @@ static void* read_finalization_pipe_data (void *data) { struct finalization_pipe_data *fdata = data; - + +#if SEMAPHORE + int consumed = 0; + sem_wait (&produce_sem); + scm_i_pthread_mutex_lock (&finalization_data_lock); + if (notify_finalizers) + { + fdata->n = 1; + fdata->byte = 0; + fdata->err = 0; + consumed = 1; + notify_finalizers = 0; + } + else if (!consumed && notify_forking) + { + fdata->n = 1; + fdata->byte = 1; + fdata->err = 0; + consumed = 1; + notify_forking = 0; + } + scm_i_pthread_mutex_unlock (&finalization_data_lock); + if (consumed) + sem_post (&consume_sem); +#else fdata->n = read (finalization_pipe[0], &fdata->byte, 1); fdata->err = errno; - +#endif return NULL; } - + static void* finalization_thread_proc (void *unused) { @@ -356,12 +421,19 @@ scm_set_automatic_finalization_enabled (int enabled_p) if (enabled_p) { #if SCM_USE_PTHREAD_THREADS +#if SEMAPHORE + if (sem_init (&produce_sem, 0, 0) == -1) + scm_syserror (NULL); + if (sem_init (&consume_sem, 0, 1) == -1) + scm_syserror (NULL); +#else /* ! SEMAPHORE */ if (pipe2 (finalization_pipe, O_CLOEXEC) != 0) scm_syserror (NULL); +#endif /* ! SEMAPHORE */ GC_set_finalizer_notifier (spawn_finalizer_thread); -#else +#else /* ! SCM_USE_PTHREAD_THREADS */ GC_set_finalizer_notifier (queue_finalizer_async); -#endif +#endif /* ! SCM_USE_PTHREAD_THREADS */ } else { @@ -369,11 +441,18 @@ scm_set_automatic_finalization_enabled (int enabled_p) #if SCM_USE_PTHREAD_THREADS stop_finalization_thread (); +#if SEMAPHORE + sem_destroy (&produce_sem); + sem_destroy (&consume_sem); + notify_finalizers = 0; + notify_forking = 0; +#else /* ! SEMAPHORE */ close (finalization_pipe[0]); close (finalization_pipe[1]); finalization_pipe[0] = -1; finalization_pipe[1] = -1; -#endif +#endif /* ! SEMAPHORE */ +#endif /* SCM_USE_PTHREAD_THREADS */ } automatic_finalization_p = enabled_p; @@ -412,9 +491,16 @@ scm_init_finalizer_thread (void) #if SCM_USE_PTHREAD_THREADS if (automatic_finalization_p) { +#if SEMAPHORE + if (sem_init (&produce_sem, 0, 0) == -1) + scm_syserror (NULL); + if (sem_init (&consume_sem, 0, 1) == -1) + scm_syserror (NULL); +#else /* ! SEMAPHORE */ if (pipe2 (finalization_pipe, O_CLOEXEC) != 0) scm_syserror (NULL); +#endif /* ! SEMAPHORE */ GC_set_finalizer_notifier (spawn_finalizer_thread); } -#endif +#endif /* SCM_USE_PTHREAD_THREADS */ } diff --git a/libguile/scmsigs.c b/libguile/scmsigs.c index 21b2a9529..b42c5bdba 100644 --- a/libguile/scmsigs.c +++ b/libguile/scmsigs.c @@ -41,6 +41,12 @@ #include <full-write.h> + +#ifdef __CYGWIN__ +#define SEMAPHORE 1 +#include <semaphore.h> +#endif + #include "libguile/_scm.h" #include "libguile/async.h" @@ -124,13 +130,29 @@ close_1 (SCM proc, SCM arg) semantics as on a proper system. If you're relying on much in the way of signal handling on mingw you probably lose anyway. */ +#if SEMAPHORE +static sem_t produce_sem; +static sem_t consume_sem; +static scm_i_pthread_mutex_t signal_data_lock = + SCM_I_PTHREAD_MUTEX_INITIALIZER; +static char notify_signal = '\0'; +#else /* ! SEMAPHORE */ static int signal_pipe[2]; +#endif static SIGRETTYPE take_signal (int signum) { char sigbyte = signum; +#if SEMAPHORE + sem_wait (&consume_sem); + scm_i_pthread_mutex_lock (&signal_data_lock); + notify_signal = sigbyte; + scm_i_pthread_mutex_unlock (&signal_data_lock); + sem_post (&produce_sem); +#else /* ! SEMAPHORE */ full_write (signal_pipe[1], &sigbyte, 1); +#endif /* ! SEMAPHORE */ #ifndef HAVE_SIGACTION signal (signum, take_signal); @@ -148,13 +170,22 @@ static void* read_signal_pipe_data (void * data) { struct signal_pipe_data *sdata = data; - +#if SEMAPHORE + sem_wait (&produce_sem); + scm_i_pthread_mutex_lock (&signal_data_lock); + sdata->n = 1; + sdata->sigbyte = notify_signal; + scm_i_pthread_mutex_unlock (&signal_data_lock); + notify_signal = '\0'; + sem_post (&consume_sem); +#else /* ! SEMAPHORE */ sdata->n = read (signal_pipe[0], &sdata->sigbyte, 1); sdata->err = errno; +#endif /* ! SEMAPHORE */ return NULL; } - + static SCM signal_delivery_thread (void *data) { @@ -175,7 +206,7 @@ signal_delivery_thread (void *data) struct signal_pipe_data sigdata; scm_without_guile (read_signal_pipe_data, &sigdata); - + sig = sigdata.sigbyte; if (sigdata.n == 1 && sig >= 0 && sig < NSIG) { @@ -202,8 +233,15 @@ start_signal_delivery_thread (void) scm_i_pthread_mutex_lock (&signal_delivery_thread_mutex); +#if SEMAPHORE + if (sem_init (&produce_sem, 0, 0) == -1) + scm_syserror (NULL); + if (sem_init (&consume_sem, 0, 1) == -1) + scm_syserror (NULL); +#else /* ! SEMAPHORE */ if (pipe2 (signal_pipe, O_CLOEXEC) != 0) scm_syserror (NULL); +#endif /* ! SEMAPHORE */ signal_thread = scm_spawn_thread (signal_delivery_thread, NULL, scm_handle_by_message, "signal delivery thread"); @@ -312,7 +350,7 @@ SCM_DEFINE (scm_sigaction_for_thread, "sigaction", 1, 3, 0, #endif int query_only = 0; int save_handler = 0; - + SCM old_handler; csig = scm_to_signed_integer (signum, 0, NSIG-1); @@ -491,7 +529,7 @@ SCM_DEFINE (scm_restore_signals, "restore-signals", 0, 0, 0, if (signal (i, orig_handlers[i]) == SIG_ERR) SCM_SYSERROR; orig_handlers[i] = SIG_ERR; - SCM_SIMPLE_VECTOR_SET (*signal_handlers, i, SCM_BOOL_F); + SCM_SIMPLE_VECTOR_SET (*signal_handlers, i, SCM_BOOL_F); } #endif } @@ -573,7 +611,7 @@ SCM_DEFINE (scm_setitimer, "setitimer", 5, 0, 0, pack_tv (&new_timer.it_value, value_seconds, value_microseconds); SCM_SYSCALL(rv = setitimer(c_which_timer, &new_timer, &old_timer)); - + if(rv != 0) SCM_SYSERROR; @@ -695,7 +733,15 @@ scm_i_close_signal_pipe() #if SCM_USE_PTHREAD_THREADS if (scm_i_signal_delivery_thread != NULL) - close (signal_pipe[1]); + { +#if SEMAPHORE + sem_destroy (&produce_sem); + sem_destroy (&consume_sem); + notify_signal = '\0'; +#else /* ! SEMAPHORE */ + close (signal_pipe[1]); +#endif /* ! SEMAPHORE */ + } #endif scm_i_pthread_mutex_unlock (&signal_delivery_thread_mutex); |