mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-07-09 10:50:27 +02:00
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
This commit is contained in:
parent
762dc83006
commit
193bda2b44
2 changed files with 148 additions and 16 deletions
|
@ -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
|
* This library is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU Lesser General Public License
|
* modify it under the terms of the GNU Lesser General Public License
|
||||||
|
@ -28,6 +28,11 @@
|
||||||
|
|
||||||
#include <full-write.h>
|
#include <full-write.h>
|
||||||
|
|
||||||
|
#ifdef __CYGWIN__
|
||||||
|
#define SEMAPHORE 1
|
||||||
|
#include <semaphore.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "libguile/bdw-gc.h"
|
#include "libguile/bdw-gc.h"
|
||||||
#include "libguile/_scm.h"
|
#include "libguile/_scm.h"
|
||||||
#include "libguile/finalizers.h"
|
#include "libguile/finalizers.h"
|
||||||
|
@ -163,8 +168,16 @@ queue_finalizer_async (void)
|
||||||
|
|
||||||
|
|
||||||
#if SCM_USE_PTHREAD_THREADS
|
#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];
|
static int finalization_pipe[2];
|
||||||
|
#endif /* ! SEMAPHORE */
|
||||||
static scm_i_pthread_mutex_t finalization_thread_lock =
|
static scm_i_pthread_mutex_t finalization_thread_lock =
|
||||||
SCM_I_PTHREAD_MUTEX_INITIALIZER;
|
SCM_I_PTHREAD_MUTEX_INITIALIZER;
|
||||||
static pthread_t finalization_thread;
|
static pthread_t finalization_thread;
|
||||||
|
@ -173,15 +186,43 @@ static int finalization_thread_is_running = 0;
|
||||||
static void
|
static void
|
||||||
notify_finalizers_to_run (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;
|
char byte = 0;
|
||||||
full_write (finalization_pipe[1], &byte, 1);
|
full_write (finalization_pipe[1], &byte, 1);
|
||||||
|
#endif /* ! SEMAPHORE */
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
notify_about_to_fork (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;
|
char byte = 1;
|
||||||
full_write (finalization_pipe[1], &byte, 1);
|
full_write (finalization_pipe[1], &byte, 1);
|
||||||
|
#endif /* ! SEMAPHORE */
|
||||||
}
|
}
|
||||||
|
|
||||||
struct finalization_pipe_data
|
struct finalization_pipe_data
|
||||||
|
@ -196,9 +237,33 @@ read_finalization_pipe_data (void *data)
|
||||||
{
|
{
|
||||||
struct finalization_pipe_data *fdata = 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->n = read (finalization_pipe[0], &fdata->byte, 1);
|
||||||
fdata->err = errno;
|
fdata->err = errno;
|
||||||
|
#endif
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -356,12 +421,19 @@ scm_set_automatic_finalization_enabled (int enabled_p)
|
||||||
if (enabled_p)
|
if (enabled_p)
|
||||||
{
|
{
|
||||||
#if SCM_USE_PTHREAD_THREADS
|
#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)
|
if (pipe2 (finalization_pipe, O_CLOEXEC) != 0)
|
||||||
scm_syserror (NULL);
|
scm_syserror (NULL);
|
||||||
|
#endif /* ! SEMAPHORE */
|
||||||
GC_set_finalizer_notifier (spawn_finalizer_thread);
|
GC_set_finalizer_notifier (spawn_finalizer_thread);
|
||||||
#else
|
#else /* ! SCM_USE_PTHREAD_THREADS */
|
||||||
GC_set_finalizer_notifier (queue_finalizer_async);
|
GC_set_finalizer_notifier (queue_finalizer_async);
|
||||||
#endif
|
#endif /* ! SCM_USE_PTHREAD_THREADS */
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -369,11 +441,18 @@ scm_set_automatic_finalization_enabled (int enabled_p)
|
||||||
|
|
||||||
#if SCM_USE_PTHREAD_THREADS
|
#if SCM_USE_PTHREAD_THREADS
|
||||||
stop_finalization_thread ();
|
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[0]);
|
||||||
close (finalization_pipe[1]);
|
close (finalization_pipe[1]);
|
||||||
finalization_pipe[0] = -1;
|
finalization_pipe[0] = -1;
|
||||||
finalization_pipe[1] = -1;
|
finalization_pipe[1] = -1;
|
||||||
#endif
|
#endif /* ! SEMAPHORE */
|
||||||
|
#endif /* SCM_USE_PTHREAD_THREADS */
|
||||||
}
|
}
|
||||||
|
|
||||||
automatic_finalization_p = enabled_p;
|
automatic_finalization_p = enabled_p;
|
||||||
|
@ -412,9 +491,16 @@ scm_init_finalizer_thread (void)
|
||||||
#if SCM_USE_PTHREAD_THREADS
|
#if SCM_USE_PTHREAD_THREADS
|
||||||
if (automatic_finalization_p)
|
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)
|
if (pipe2 (finalization_pipe, O_CLOEXEC) != 0)
|
||||||
scm_syserror (NULL);
|
scm_syserror (NULL);
|
||||||
|
#endif /* ! SEMAPHORE */
|
||||||
GC_set_finalizer_notifier (spawn_finalizer_thread);
|
GC_set_finalizer_notifier (spawn_finalizer_thread);
|
||||||
}
|
}
|
||||||
#endif
|
#endif /* SCM_USE_PTHREAD_THREADS */
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,6 +41,12 @@
|
||||||
|
|
||||||
#include <full-write.h>
|
#include <full-write.h>
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __CYGWIN__
|
||||||
|
#define SEMAPHORE 1
|
||||||
|
#include <semaphore.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "libguile/_scm.h"
|
#include "libguile/_scm.h"
|
||||||
|
|
||||||
#include "libguile/async.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
|
semantics as on a proper system. If you're relying on much in the way of
|
||||||
signal handling on mingw you probably lose anyway. */
|
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];
|
static int signal_pipe[2];
|
||||||
|
#endif
|
||||||
|
|
||||||
static SIGRETTYPE
|
static SIGRETTYPE
|
||||||
take_signal (int signum)
|
take_signal (int signum)
|
||||||
{
|
{
|
||||||
char sigbyte = 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);
|
full_write (signal_pipe[1], &sigbyte, 1);
|
||||||
|
#endif /* ! SEMAPHORE */
|
||||||
|
|
||||||
#ifndef HAVE_SIGACTION
|
#ifndef HAVE_SIGACTION
|
||||||
signal (signum, take_signal);
|
signal (signum, take_signal);
|
||||||
|
@ -148,9 +170,18 @@ static void*
|
||||||
read_signal_pipe_data (void * data)
|
read_signal_pipe_data (void * data)
|
||||||
{
|
{
|
||||||
struct signal_pipe_data *sdata = 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->n = read (signal_pipe[0], &sdata->sigbyte, 1);
|
||||||
sdata->err = errno;
|
sdata->err = errno;
|
||||||
|
#endif /* ! SEMAPHORE */
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -202,8 +233,15 @@ start_signal_delivery_thread (void)
|
||||||
|
|
||||||
scm_i_pthread_mutex_lock (&signal_delivery_thread_mutex);
|
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)
|
if (pipe2 (signal_pipe, O_CLOEXEC) != 0)
|
||||||
scm_syserror (NULL);
|
scm_syserror (NULL);
|
||||||
|
#endif /* ! SEMAPHORE */
|
||||||
signal_thread = scm_spawn_thread (signal_delivery_thread, NULL,
|
signal_thread = scm_spawn_thread (signal_delivery_thread, NULL,
|
||||||
scm_handle_by_message,
|
scm_handle_by_message,
|
||||||
"signal delivery thread");
|
"signal delivery thread");
|
||||||
|
@ -695,7 +733,15 @@ scm_i_close_signal_pipe()
|
||||||
|
|
||||||
#if SCM_USE_PTHREAD_THREADS
|
#if SCM_USE_PTHREAD_THREADS
|
||||||
if (scm_i_signal_delivery_thread != NULL)
|
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
|
#endif
|
||||||
|
|
||||||
scm_i_pthread_mutex_unlock (&signal_delivery_thread_mutex);
|
scm_i_pthread_mutex_unlock (&signal_delivery_thread_mutex);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue