summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Gran <spk121@yahoo.com>2017-04-04 08:03:33 -0700
committerMichael Gran <spk121@yahoo.com>2017-04-04 08:03:33 -0700
commit193bda2b442988e926b478e6bdb09b5d1d75d422 (patch)
tree6b267f06b2db8fe0c3f43ead6d14d08381a56eee
parent762dc83006f4677f125de78becf1144a9c16180b (diff)
downloadguile-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.c104
-rw-r--r--libguile/scmsigs.c60
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);