guile-commits
[Top][All Lists]
Advanced

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

[Guile-commits] GNU Guile branch, master, updated. v2.1.0-68-g79eb47e


From: Andy Wingo
Subject: [Guile-commits] GNU Guile branch, master, updated. v2.1.0-68-g79eb47e
Date: Fri, 24 Feb 2012 22:07:15 +0000

This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "GNU Guile".

http://git.savannah.gnu.org/cgit/guile.git/commit/?id=79eb47ea47650ef42c545931726277a7118a0210

The branch, master has been updated
       via  79eb47ea47650ef42c545931726277a7118a0210 (commit)
       via  2dcf6b596526429d75f1b53ee53d64dbbfc83b53 (commit)
      from  f9c3584117d32680af91a5b2a10e262e8176bd61 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit 79eb47ea47650ef42c545931726277a7118a0210
Author: Andy Wingo <address@hidden>
Date:   Fri Feb 24 23:05:02 2012 +0100

    port i/o optimizations for iso-8859-1
    
    * libguile/ports.h (scm_t_port_encoding_mode):
    * libguile/ports.c (scm_c_make_port_with_encoding):
      (scm_i_set_port_encoding_x): Add special treatment for latin1
      encoding.
      (get_latin1_codepoint, get_codepoint): Add latin1 fast-path.
    
    * libguile/print.c (display_string_as_latin1): Add latin1 fastpath.

commit 2dcf6b596526429d75f1b53ee53d64dbbfc83b53
Author: Andy Wingo <address@hidden>
Date:   Fri Feb 24 23:03:31 2012 +0100

    fixes to threaded finalizers
    
    * libguile/finalizers.c (finalization_thread_proc):
      (run_finalization_thread):
      (start_finalization_thread):
      (stop_finalization_thread): Use pthreads + scm_with_guile instead of
      scm_spawn_thread, to avoid deadlocks.

-----------------------------------------------------------------------

Summary of changes:
 libguile/finalizers.c |   35 +++++++++++++++++++++-----------
 libguile/ports.c      |   35 ++++++++++++++++++++++++++++---
 libguile/ports.h      |    1 +
 libguile/print.c      |   53 +++++++++++++++++++++++++++++++++++++++++++++++-
 4 files changed, 106 insertions(+), 18 deletions(-)

diff --git a/libguile/finalizers.c b/libguile/finalizers.c
index cabfa2c..07d8f07 100644
--- a/libguile/finalizers.c
+++ b/libguile/finalizers.c
@@ -171,7 +171,7 @@ queue_finalizer_async (void)
 static int finalization_pipe[2];
 static scm_i_pthread_mutex_t finalization_thread_lock =
   SCM_I_PTHREAD_MUTEX_INITIALIZER;
-static SCM finalization_thread = SCM_BOOL_F;
+static pthread_t finalization_thread;
 
 static void
 notify_finalizers_to_run (void)
@@ -205,7 +205,7 @@ read_finalization_pipe_data (void *data)
   return NULL;
 }
   
-static SCM
+static void*
 finalization_thread_proc (void *unused)
 {
   while (1)
@@ -216,8 +216,8 @@ finalization_thread_proc (void *unused)
       
       if (data.n <= 0 && data.err != EINTR) 
         {
-          perror ("error in finalization delivery thread");
-          return SCM_UNSPECIFIED;
+          perror ("error in finalization thread");
+          return NULL;
         }
 
       switch (data.byte)
@@ -226,21 +226,31 @@ finalization_thread_proc (void *unused)
           finalization_count += GC_invoke_finalizers ();
           break;
         case 1:
-          return SCM_UNSPECIFIED;
+          return NULL;
         default:
           abort ();
         }
     }
 }
 
+static void*
+run_finalization_thread (void *arg)
+{
+  return scm_with_guile (finalization_thread_proc, arg);
+}
+
 static void
 start_finalization_thread (void)
 {
   scm_i_pthread_mutex_lock (&finalization_thread_lock);
-  if (scm_is_false (finalization_thread))
-    finalization_thread = scm_spawn_thread (finalization_thread_proc, NULL,
-                                            scm_handle_by_message,
-                                            "finalization thread");
+  if (!finalization_thread)
+    /* Use the raw pthread API and scm_with_guile, because we don't want
+       to block on any lock that scm_spawn_thread might want to take,
+       and we don't want to inherit the dynamic state (fluids) of the
+       caller.  */
+    if (pthread_create (&finalization_thread, NULL,
+                        run_finalization_thread, NULL))
+      perror ("error creating finalization thread");
   scm_i_pthread_mutex_unlock (&finalization_thread_lock);
 }
 
@@ -248,11 +258,12 @@ static void
 stop_finalization_thread (void)
 {
   scm_i_pthread_mutex_lock (&finalization_thread_lock);
-  if (scm_is_true (finalization_thread))
+  if (finalization_thread)
     {
       notify_about_to_fork ();
-      scm_join_thread (finalization_thread);
-      finalization_thread = SCM_BOOL_F;
+      if (pthread_join (finalization_thread, NULL))
+        perror ("joining finalization thread");
+      finalization_thread = 0;
     }
   scm_i_pthread_mutex_unlock (&finalization_thread_lock);
 }
diff --git a/libguile/ports.c b/libguile/ports.c
index 5b98bf9..e17ea06 100644
--- a/libguile/ports.c
+++ b/libguile/ports.c
@@ -605,6 +605,8 @@ scm_c_make_port_with_encoding (scm_t_bits tag, unsigned 
long mode_bits,
   entry->encoding = encoding ? scm_gc_strdup (encoding, "port") : NULL;
   if (encoding && strcmp (encoding, "UTF-8") == 0)
     entry->encoding_mode = SCM_PORT_ENCODING_MODE_UTF8;
+  else if (!encoding || strcmp (encoding, "ISO-8859-1") == 0)
+    entry->encoding_mode = SCM_PORT_ENCODING_MODE_LATIN1;
   else
     entry->encoding_mode = SCM_PORT_ENCODING_MODE_ICONV;
   entry->ilseq_handler = handler;
@@ -941,15 +943,18 @@ scm_i_set_port_encoding_x (SCM port, const char *encoding)
   pt = SCM_PTAB_ENTRY (port);
   prev = pt->iconv_descriptors;
 
-  if (encoding == NULL)
-    encoding = "ISO-8859-1";
-
-  if (strcmp (encoding, "UTF-8") == 0)
+  if (encoding && strcmp (encoding, "UTF-8") == 0)
     {
       pt->encoding = "UTF-8";
       pt->encoding_mode = SCM_PORT_ENCODING_MODE_UTF8;
       pt->iconv_descriptors = NULL;
     }
+  else if (!encoding || strcmp (encoding, "ISO-8859-1") == 0)
+    {
+      pt->encoding = "ISO-8859-1";
+      pt->encoding_mode = SCM_PORT_ENCODING_MODE_LATIN1;
+      pt->iconv_descriptors = NULL;
+    }
   else
     {
       /* Open descriptors before mutating the port. */
@@ -1582,6 +1587,26 @@ get_utf8_codepoint (SCM port, scm_t_wchar *codepoint,
 #undef ASSERT_NOT_EOF
 }
 
+/* Read an ISO-8859-1 codepoint (a byte) from PORT.  On success, return
+   *0 and set CODEPOINT to the codepoint that was read, fill BUF with
+   *its UTF-8 representation, and set *LEN to the length in bytes.
+   *Return `EILSEQ' on error.  */
+static int
+get_latin1_codepoint (SCM port, scm_t_wchar *codepoint,
+                      char buf[SCM_MBCHAR_BUF_SIZE], size_t *len)
+{
+  *codepoint = scm_get_byte_or_eof_unlocked (port);
+
+  if (*codepoint == EOF)
+    *len = 0;
+  else
+    {
+      *len = 1;
+      buf[0] = *codepoint;
+    }
+  return 0;
+}
+
 /* Likewise, read a byte sequence from PORT, passing it through its
    input conversion descriptor.  */
 static int
@@ -1662,6 +1687,8 @@ get_codepoint (SCM port, scm_t_wchar *codepoint,
 
   if (pt->encoding_mode == SCM_PORT_ENCODING_MODE_UTF8)
     err = get_utf8_codepoint (port, codepoint, (scm_t_uint8 *) buf, len);
+  else if (pt->encoding_mode == SCM_PORT_ENCODING_MODE_LATIN1)
+    err = get_latin1_codepoint (port, codepoint, buf, len);
   else
     err = get_iconv_codepoint (port, codepoint, buf, len);
 
diff --git a/libguile/ports.h b/libguile/ports.h
index c42b501..2d277e0 100644
--- a/libguile/ports.h
+++ b/libguile/ports.h
@@ -50,6 +50,7 @@ typedef enum scm_t_port_rw_active {
 
 typedef enum scm_t_port_encoding_mode {
   SCM_PORT_ENCODING_MODE_UTF8,
+  SCM_PORT_ENCODING_MODE_LATIN1,
   SCM_PORT_ENCODING_MODE_ICONV
 } scm_t_port_encoding_mode;
 
diff --git a/libguile/print.c b/libguile/print.c
index a1bf5ed..eb60132 100644
--- a/libguile/print.c
+++ b/libguile/print.c
@@ -853,6 +853,54 @@ display_string_as_utf8 (const void *str, int narrow_p, 
size_t len,
   return len;
 }
 
+/* Write STR to PORT as ISO-8859-1.  STR is a LEN-codepoint string; it
+   is narrow if NARROW_P is true, wide otherwise.  Return LEN.  */
+static size_t
+display_string_as_latin1 (const void *str, int narrow_p, size_t len,
+                          SCM port,
+                          scm_t_string_failed_conversion_handler strategy)
+{
+  size_t printed = 0;
+
+  if (narrow_p)
+    {
+      scm_lfwrite_unlocked (str, len, port);
+      return len;
+    }
+
+  while (printed < len)
+    {
+      char buf[256];
+      size_t i;
+
+      for (i = 0; i < sizeof(buf) && printed < len; i++, printed++)
+        {
+          scm_t_wchar c = STR_REF (str, printed);
+
+          if (c < 256)
+            buf[i] = c;
+          else
+            break;
+        }
+
+      scm_lfwrite_unlocked (buf, i, port);
+
+      if (i < sizeof(buf) && printed < len)
+        {
+          if (strategy == SCM_FAILED_CONVERSION_ERROR)
+            break;
+          else if (strategy == SCM_FAILED_CONVERSION_ESCAPE_SEQUENCE)
+            write_character_escaped (STR_REF (str, printed), 1, port);
+          else
+            /* STRATEGY is `SCM_FAILED_CONVERSION_QUESTION_MARK'.  */
+            display_string ("?", 1, 1, port, strategy);
+          printed++;
+        }
+    }
+
+  return printed;
+}
+
 /* Convert STR through PORT's output conversion descriptor and write the
    output to PORT.  Return the number of codepoints written.  */
 static size_t
@@ -968,9 +1016,10 @@ display_string (const void *str, int narrow_p,
 
   if (pt->encoding_mode == SCM_PORT_ENCODING_MODE_UTF8)
     return display_string_as_utf8 (str, narrow_p, len, port);
+  else if (pt->encoding_mode == SCM_PORT_ENCODING_MODE_LATIN1)
+    return display_string_as_latin1 (str, narrow_p, len, port, strategy);
   else
-    return display_string_using_iconv (str, narrow_p, len,
-                                      port, strategy);
+    return display_string_using_iconv (str, narrow_p, len, port, strategy);
 }
 
 /* Attempt to display CH to PORT according to STRATEGY.  Return non-zero


hooks/post-receive
-- 
GNU Guile



reply via email to

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