guile-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Guile-commits] 02/07: prefer producer/consumer to pipes on Cygwin


From: Mike Gran
Subject: [Guile-commits] 02/07: prefer producer/consumer to pipes on Cygwin
Date: Tue, 4 Apr 2017 12:16:46 -0400 (EDT)

mike121 pushed a commit to branch wip-cygwin-guile-2.2
in repository guile.

commit 193bda2b442988e926b478e6bdb09b5d1d75d422
Author: Michael Gran <address@hidden>
Date:   Tue Apr 4 08:03:33 2017 -0700

    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
---
 libguile/finalizers.c | 104 +++++++++++++++++++++++++++++++++++++++++++++-----
 libguile/scmsigs.c    |  60 +++++++++++++++++++++++++----
 2 files changed, 148 insertions(+), 16 deletions(-)

diff --git a/libguile/finalizers.c b/libguile/finalizers.c
index c5d69e8..36be6c3 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 21b2a95..b42c5bd 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);



reply via email to

[Prev in Thread] Current Thread [Next in Thread]