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-108-g62bd5d6


From: Andy Wingo
Subject: [Guile-commits] GNU Guile branch, master, updated. v2.1.0-108-g62bd5d6
Date: Mon, 07 Nov 2011 18:07:54 +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=62bd5d66cb66b695452887374c55d025b8b6efea

The branch, master has been updated
       via  62bd5d66cb66b695452887374c55d025b8b6efea (commit)
       via  a535e9f54c35bb90bfa272ed040fe71825ce03dd (commit)
       via  422866a7c6a16b123f43610d9499d602d6b4744f (commit)
       via  891702eaef9d2554fae44ab76bcfa1a9a4bb645e (commit)
       via  fca14149081889576f9f6a65f91270b4f4d611d3 (commit)
       via  30b126d2bad540f1f508917214467529cb05a3d3 (commit)
      from  0f9f51a153db3e669a12c416c4958d71bd3c2a8b (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 62bd5d66cb66b695452887374c55d025b8b6efea
Author: Andy Wingo <address@hidden>
Date:   Mon Nov 7 18:58:01 2011 +0100

    threadsafe access to scm_ptobs
    
    * libguile/ports.h (SCM_PORT_DESCRIPTOR): New macro, to get at a port
      descriptor in the third word of a port instead of looking it up in a
      table.
      (scm_c_port_type_ref, scm_c_port_type_add_x): New API for working with
      numbered ptob descriptors.
      (SCM_PTOBNAME): Implement in terms of scm_c_port_type_ref.
      (scm_get_byte_or_eof, scm_peek_byte_or_eof): Use SCM_PORT_DESCRIPTOR.
    
    * libguile/ports.c (scm_c_num_port_types, scm_c_port_type_ref)
      (scm_c_port_type_add_x, scm_make_port_type): Protect scm_ptobs access
      with a mutex.  Have it be an array of pointers instead of an array of
      structures.  Adapt users to the new APIs.
      (scm_c_make_port_with_encoding): Allocate ports with three words.  The
      third word is the ptob descriptor.
    
    * libguile/backtrace.c:
    * libguile/goops.c:
    * libguile/ioext.c:
    * libguile/print.c: Adapt to use scm_c_port_type_ref and
      SCM_PORT_DESCRIPTOR.

commit a535e9f54c35bb90bfa272ed040fe71825ce03dd
Author: Andy Wingo <address@hidden>
Date:   Mon Nov 7 17:08:31 2011 +0100

    reorder ports.h declarations
    
    * libguile/ports.h: Reorder declarations.

commit 422866a7c6a16b123f43610d9499d602d6b4744f
Author: Andy Wingo <address@hidden>
Date:   Mon Nov 7 16:25:37 2011 +0100

    remove scm_markstream
    
    * libguile/ports.h:
    * libguile/ports.c (scm_markstream): Remove obsolete definition.  Moved
      around a couple of other declarations.

commit 891702eaef9d2554fae44ab76bcfa1a9a4bb645e
Author: Andy Wingo <address@hidden>
Date:   Mon Nov 7 16:22:55 2011 +0100

    ports.h: remove unimplemented declarations
    
    * libguile/ports.h (scm_grow_port_cbuf, scm_pt_size, scm_pt_member):
      Remove declarations of unimplemented functions.  Move a couple of
      other definitions around.

commit fca14149081889576f9f6a65f91270b4f4d611d3
Author: Andy Wingo <address@hidden>
Date:   Mon Nov 7 16:14:15 2011 +0100

    inlined port functions to ports.h
    
    * libguile/inline.h:
    * libguile/ports.h (scm_get_byte_or_eof, scm_peek_byte_or_eof)
      (scm_putc, scm_puts): Move definitions here, from inline.h.

commit 30b126d2bad540f1f508917214467529cb05a3d3
Author: Andy Wingo <address@hidden>
Date:   Mon Nov 7 16:01:01 2011 +0100

    add lock to scm_t_port
    
    * libguile/ports.h (scm_c_lock_port, scm_c_try_lock_port)
      (scm_c_unlock_port): New inline functions.
      (scm_t_port): Add a lock field, if threads are enabled.  This is a
      first step towards threadsafe ports.
    
    * libguile/ports.c (scm_c_make_port_with_encoding): Init the port's
      lock.
    
    * libguile/inline.c: Residualize the inline functions from ports.h.

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

Summary of changes:
 libguile/backtrace.c |    2 +-
 libguile/goops.c     |    2 +-
 libguile/inline.c    |    1 +
 libguile/inline.h    |   75 ---------------
 libguile/ioext.c     |    2 +-
 libguile/ports.c     |  209 ++++++++++++++++++++++++----------------
 libguile/ports.h     |  256 +++++++++++++++++++++++++++++++++++++-------------
 libguile/print.c     |    8 +-
 8 files changed, 324 insertions(+), 231 deletions(-)

diff --git a/libguile/backtrace.c b/libguile/backtrace.c
index a9b37fd..4dacae2 100644
--- a/libguile/backtrace.c
+++ b/libguile/backtrace.c
@@ -214,7 +214,7 @@ static void
 display_frame_expr (char *hdr, SCM exp, char *tlr, int indentation, SCM sport, 
SCM port, scm_print_state *pstate)
 {
   int i = 0, n;
-  scm_t_ptob_descriptor *ptob = scm_ptobs + SCM_PTOBNUM (sport);
+  scm_t_ptob_descriptor *ptob = SCM_PORT_DESCRIPTOR (sport);
   do
     {
       pstate->length = print_params[i].length;
diff --git a/libguile/goops.c b/libguile/goops.c
index 3c82d6d..d82a42f 100644
--- a/libguile/goops.c
+++ b/libguile/goops.c
@@ -2698,7 +2698,7 @@ create_port_classes (void)
 {
   long i;
 
-  for (i = 0; i < scm_numptob; ++i)
+  for (i = scm_c_num_port_types () - 1; i >= 0; i--)
     scm_make_port_classes (i, SCM_PTOBNAME (i));
 }
 
diff --git a/libguile/inline.c b/libguile/inline.c
index be7670a..7b900f7 100644
--- a/libguile/inline.c
+++ b/libguile/inline.c
@@ -25,3 +25,4 @@
 #include "libguile/inline.h"
 #include "libguile/gc.h"
 #include "libguile/smob.h"
+#include "libguile/ports.h"
diff --git a/libguile/inline.h b/libguile/inline.h
index 315240e..fe9cac7 100644
--- a/libguile/inline.h
+++ b/libguile/inline.h
@@ -27,9 +27,6 @@
    platforms that do support inline functions, the definitions are still
    compiled into the library, once, in inline.c.  */
 
-#include <stdio.h>
-#include <string.h>
-
 #include "libguile/__scm.h"
 
 #include "libguile/pairs.h"
@@ -47,12 +44,6 @@ SCM_INLINE void scm_array_handle_set (scm_t_array_handle *h, 
ssize_t pos, SCM va
 SCM_INLINE int scm_is_pair (SCM x);
 SCM_INLINE int scm_is_string (SCM x);
 
-SCM_INLINE int scm_get_byte_or_eof (SCM port);
-SCM_INLINE int scm_peek_byte_or_eof (SCM port);
-SCM_INLINE void scm_putc (char c, SCM port);
-SCM_INLINE void scm_puts (const char *str_data, SCM port);
-
-
 SCM_INLINE SCM scm_cell (scm_t_bits car, scm_t_bits cdr);
 SCM_INLINE SCM scm_double_cell (scm_t_bits car, scm_t_bits cbr,
                             scm_t_bits ccr, scm_t_bits cdr);
@@ -114,71 +105,5 @@ scm_is_string (SCM x)
   return SCM_HAS_TYP7 (x, scm_tc7_string);
 }
 
-/* Port I/O.  */
-
-SCM_INLINE_IMPLEMENTATION int
-scm_get_byte_or_eof (SCM port)
-{
-  int c;
-  scm_t_port *pt = SCM_PTAB_ENTRY (port);
-
-  if (pt->rw_active == SCM_PORT_WRITE)
-    /* may be marginally faster than calling scm_flush.  */
-    scm_ptobs[SCM_PTOBNUM (port)].flush (port);
-
-  if (pt->rw_random)
-    pt->rw_active = SCM_PORT_READ;
-
-  if (pt->read_pos >= pt->read_end)
-    {
-      if (SCM_UNLIKELY (scm_fill_input (port) == EOF))
-       return EOF;
-    }
-
-  c = *(pt->read_pos++);
-
-  return c;
-}
-
-/* Like `scm_get_byte_or_eof' but does not change PORT's `read_pos'.  */
-SCM_INLINE_IMPLEMENTATION int
-scm_peek_byte_or_eof (SCM port)
-{
-  int c;
-  scm_t_port *pt = SCM_PTAB_ENTRY (port);
-
-  if (pt->rw_active == SCM_PORT_WRITE)
-    /* may be marginally faster than calling scm_flush.  */
-    scm_ptobs[SCM_PTOBNUM (port)].flush (port);
-
-  if (pt->rw_random)
-    pt->rw_active = SCM_PORT_READ;
-
-  if (pt->read_pos >= pt->read_end)
-    {
-      if (SCM_UNLIKELY (scm_fill_input (port) == EOF))
-       return EOF;
-    }
-
-  c = *pt->read_pos;
-
-  return c;
-}
-
-SCM_INLINE_IMPLEMENTATION void
-scm_putc (char c, SCM port)
-{
-  SCM_ASSERT_TYPE (SCM_OPOUTPORTP (port), port, 0, NULL, "output port");
-  scm_lfwrite (&c, 1, port);
-}
-
-SCM_INLINE_IMPLEMENTATION void
-scm_puts (const char *s, SCM port)
-{
-  SCM_ASSERT_TYPE (SCM_OPOUTPORTP (port), port, 0, NULL, "output port");
-  scm_lfwrite (s, strlen (s), port);
-}
-
-
 #endif
 #endif
diff --git a/libguile/ioext.c b/libguile/ioext.c
index cb55fb2..f2b1d6d 100644
--- a/libguile/ioext.c
+++ b/libguile/ioext.c
@@ -89,7 +89,7 @@ SCM_DEFINE (scm_redirect_port, "redirect-port", 2, 0, 0,
     {
       scm_t_port *pt = SCM_PTAB_ENTRY (new);
       scm_t_port *old_pt = SCM_PTAB_ENTRY (old);
-      scm_t_ptob_descriptor *ptob = &scm_ptobs[SCM_PTOBNUM (new)];
+      scm_t_ptob_descriptor *ptob = SCM_PORT_DESCRIPTOR (new);
 
       /* must flush to old fdes.  */
       if (pt->rw_active == SCM_PORT_WRITE)
diff --git a/libguile/ports.c b/libguile/ports.c
index b6b3aa9..9b00cc0 100644
--- a/libguile/ports.c
+++ b/libguile/ports.c
@@ -98,19 +98,79 @@
  * Indexes into this table are used when generating type
  * tags for smobjects (if you know a tag you can get an index and conversely).
  */
-scm_t_ptob_descriptor *scm_ptobs = NULL;
-long scm_numptob = 0;
+static scm_t_ptob_descriptor **scm_ptobs = NULL;
+static long scm_numptob = 0; /* Number of port types.  */
+static long scm_ptobs_size = 0; /* Number of slots in the port type
+                                   table.  */
+static scm_i_pthread_mutex_t scm_ptobs_lock = SCM_I_PTHREAD_MUTEX_INITIALIZER;
 
-/* GC marker for a port with stream of SCM type.  */
-SCM 
-scm_markstream (SCM ptr)
+long
+scm_c_num_port_types (void)
 {
-  int openp;
-  openp = SCM_CELL_WORD_0 (ptr) & SCM_OPN;
-  if (openp)
-    return SCM_PACK (SCM_STREAM (ptr));
-  else
-    return SCM_BOOL_F;
+  long ret;
+  
+  scm_i_pthread_mutex_lock (&scm_ptobs_lock);
+  ret = scm_numptob;
+  scm_i_pthread_mutex_unlock (&scm_ptobs_lock);
+
+  return ret;
+}
+
+scm_t_ptob_descriptor*
+scm_c_port_type_ref (long ptobnum)
+{
+  scm_t_ptob_descriptor *ret = NULL;
+
+  scm_i_pthread_mutex_lock (&scm_ptobs_lock);
+
+  if (0 <= ptobnum && ptobnum < scm_numptob)
+    ret = scm_ptobs[ptobnum];
+
+  scm_i_pthread_mutex_unlock (&scm_ptobs_lock);
+
+  if (!ret)
+    scm_out_of_range ("scm_c_port_type_ref", scm_from_long (ptobnum));
+
+  return ret;
+}
+
+long
+scm_c_port_type_add_x (scm_t_ptob_descriptor *desc)
+{
+  long ret = -1;
+
+  scm_i_pthread_mutex_lock (&scm_ptobs_lock);
+  
+  if (scm_numptob + 1 < SCM_I_MAX_PORT_TYPE_COUNT)
+    {
+      if (scm_numptob == scm_ptobs_size)
+        {
+          unsigned long old_size = scm_ptobs_size;
+          scm_t_ptob_descriptor **old_ptobs = scm_ptobs;
+      
+          /* Currently there are only 9 predefined port types, so one
+             resize will cover it.  */
+          scm_ptobs_size = old_size + 10;
+
+          if (scm_ptobs_size >= SCM_I_MAX_PORT_TYPE_COUNT)
+            scm_ptobs_size = SCM_I_MAX_PORT_TYPE_COUNT;
+
+          scm_ptobs = scm_gc_malloc (sizeof (*scm_ptobs) * scm_ptobs_size,
+                                     "scm_ptobs");
+
+          memcpy (scm_ptobs, old_ptobs, sizeof (*scm_ptobs) * scm_numptob);
+        }
+
+      ret = scm_numptob++;
+      scm_ptobs[ret] = desc;
+    }
+  
+  scm_i_pthread_mutex_unlock (&scm_ptobs_lock);
+
+  if (ret < 0)
+    scm_out_of_range ("scm_c_port_type_add_x", scm_from_long (scm_numptob));
+
+  return ret;
 }
 
 /*
@@ -134,110 +194,88 @@ scm_make_port_type (char *name,
                    int (*fill_input) (SCM port),
                    void (*write) (SCM port, const void *data, size_t size))
 {
-  char *tmp;
-  if (SCM_I_MAX_PORT_TYPE_COUNT - 1 <= scm_numptob)
-    goto ptoberr;
-  SCM_CRITICAL_SECTION_START;
-  tmp = (char *) scm_gc_realloc ((char *) scm_ptobs,
-                                scm_numptob * sizeof (scm_t_ptob_descriptor),
-                                (1 + scm_numptob)
-                                * sizeof (scm_t_ptob_descriptor),
-                                "port-type");
-  if (tmp)
-    {
-      scm_ptobs = (scm_t_ptob_descriptor *) tmp;
-
-      scm_ptobs[scm_numptob].name = name;
-      scm_ptobs[scm_numptob].mark = 0;
-      scm_ptobs[scm_numptob].free = NULL;
-      scm_ptobs[scm_numptob].print = scm_port_print;
-      scm_ptobs[scm_numptob].equalp = 0;
-      scm_ptobs[scm_numptob].close = 0;
+  scm_t_ptob_descriptor *desc;
+  long ptobnum;
 
-      scm_ptobs[scm_numptob].write = write;
-      scm_ptobs[scm_numptob].flush = flush_port_default;
+  desc = scm_gc_malloc_pointerless (sizeof (*desc), "port-type");
+  memset (desc, 0, sizeof (*desc));
 
-      scm_ptobs[scm_numptob].end_input = end_input_default;
-      scm_ptobs[scm_numptob].fill_input = fill_input;
-      scm_ptobs[scm_numptob].input_waiting = 0;
+  desc->name = name;
+  desc->print = scm_port_print;
+  desc->write = write;
+  desc->flush = flush_port_default;
+  desc->end_input = end_input_default;
+  desc->fill_input = fill_input;
 
-      scm_ptobs[scm_numptob].seek = 0;
-      scm_ptobs[scm_numptob].truncate = 0;
+  ptobnum = scm_c_port_type_add_x (desc);
 
-      scm_numptob++;
-    }
-  SCM_CRITICAL_SECTION_END;
-  if (!tmp)
-    {
-    ptoberr:
-      scm_memory_error ("scm_make_port_type");
-    }
-  /* Make a class object if Goops is present */
+  /* Make a class object if GOOPS is present.  */
   if (SCM_UNPACK (scm_port_class[0]) != 0)
-    scm_make_port_classes (scm_numptob - 1, SCM_PTOBNAME (scm_numptob - 1));
-  return scm_tc7_port + (scm_numptob - 1) * 256;
+    scm_make_port_classes (ptobnum, name);
+
+  return scm_tc7_port + ptobnum * 256;
 }
 
 void
 scm_set_port_mark (scm_t_bits tc, SCM (*mark) (SCM))
 {
-  scm_ptobs[SCM_TC2PTOBNUM (tc)].mark = mark;
+  scm_c_port_type_ref (SCM_TC2PTOBNUM (tc))->mark = mark;
 }
 
 void
 scm_set_port_free (scm_t_bits tc, size_t (*free) (SCM))
 {
-  scm_ptobs[SCM_TC2PTOBNUM (tc)].free = free;
+  scm_c_port_type_ref (SCM_TC2PTOBNUM (tc))->free = free;
 }
 
 void
 scm_set_port_print (scm_t_bits tc, int (*print) (SCM exp, SCM port,
                                           scm_print_state *pstate))
 {
-  scm_ptobs[SCM_TC2PTOBNUM (tc)].print = print;
+  scm_c_port_type_ref (SCM_TC2PTOBNUM (tc))->print = print;
 }
 
 void
 scm_set_port_equalp (scm_t_bits tc, SCM (*equalp) (SCM, SCM))
 {
-  scm_ptobs[SCM_TC2PTOBNUM (tc)].equalp = equalp;
+  scm_c_port_type_ref (SCM_TC2PTOBNUM (tc))->equalp = equalp;
 }
 
 void
 scm_set_port_flush (scm_t_bits tc, void (*flush) (SCM port))
 {
-   scm_ptobs[SCM_TC2PTOBNUM (tc)].flush = flush;
+   scm_c_port_type_ref (SCM_TC2PTOBNUM (tc))->flush = flush;
 }
 
 void
 scm_set_port_end_input (scm_t_bits tc, void (*end_input) (SCM port, int 
offset))
 {
-  scm_ptobs[SCM_TC2PTOBNUM (tc)].end_input = end_input;
+  scm_c_port_type_ref (SCM_TC2PTOBNUM (tc))->end_input = end_input;
 }
 
 void
 scm_set_port_close (scm_t_bits tc, int (*close) (SCM))
 {
-  scm_ptobs[SCM_TC2PTOBNUM (tc)].close = close;
+  scm_c_port_type_ref (SCM_TC2PTOBNUM (tc))->close = close;
 }
 
 void
 scm_set_port_seek (scm_t_bits tc,
                   scm_t_off (*seek) (SCM, scm_t_off, int))
 {
-  scm_ptobs[SCM_TC2PTOBNUM (tc)].seek = seek;
+  scm_c_port_type_ref (SCM_TC2PTOBNUM (tc))->seek = seek;
 }
 
 void
 scm_set_port_truncate (scm_t_bits tc, void (*truncate) (SCM, scm_t_off))
 {
-  scm_ptobs[SCM_TC2PTOBNUM (tc)].truncate = truncate;
+  scm_c_port_type_ref (SCM_TC2PTOBNUM (tc))->truncate = truncate;
 }
 
 void
 scm_set_port_input_waiting (scm_t_bits tc, int (*input_waiting) (SCM))
 {
-  scm_ptobs[SCM_TC2PTOBNUM (tc)].input_waiting = input_waiting;
+  scm_c_port_type_ref (SCM_TC2PTOBNUM (tc))->input_waiting = input_waiting;
 }
 
 
@@ -279,7 +317,7 @@ SCM_DEFINE (scm_char_ready_p, "char-ready?", 0, 1, 0,
     return SCM_BOOL_T;
   else
     {
-      scm_t_ptob_descriptor *ptob = &scm_ptobs[SCM_PTOBNUM (port)];
+      scm_t_ptob_descriptor *ptob = SCM_PORT_DESCRIPTOR (port);
       
       if (ptob->input_waiting)
        return scm_from_bool(ptob->input_waiting (port));
@@ -291,7 +329,8 @@ SCM_DEFINE (scm_char_ready_p, "char-ready?", 0, 1, 0,
 
 /* move up to read_len chars from port's putback and/or read buffers
    into memory starting at dest.  returns the number of chars moved.  */
-size_t scm_take_from_input_buffers (SCM port, char *dest, size_t read_len)
+size_t
+scm_take_from_input_buffers (SCM port, char *dest, size_t read_len)
 {
   scm_t_port *pt = SCM_PTAB_ENTRY (port);
   size_t chars_read = 0;
@@ -535,7 +574,6 @@ register_finalizer_for_port (SCM port)
 static void
 finalize_port (GC_PTR ptr, GC_PTR data)
 {
-  long port_type;
   SCM port = SCM_PACK_POINTER (ptr);
 
   if (!SCM_PORTP (port))
@@ -548,16 +586,13 @@ finalize_port (GC_PTR ptr, GC_PTR data)
        register_finalizer_for_port (port);
       else
        {
+          scm_t_ptob_descriptor *ptob = SCM_PORT_DESCRIPTOR (port);
          scm_t_port *entry;
 
-         port_type = SCM_TC2PTOBNUM (SCM_CELL_TYPE (port));
-         if (port_type >= scm_numptob)
-           abort ();
-
-         if (scm_ptobs[port_type].free)
-           /* Yes, I really do mean `.free' rather than `.close'.  `.close'
+         if (ptob->free)
+           /* Yes, I really do mean `free' rather than `close'.  `close'
               is for explicit `close-port' by user.  */
-           scm_ptobs[port_type].free (port);
+           ptob->free (port);
 
          entry = SCM_PTAB_ENTRY (port);
 
@@ -586,9 +621,18 @@ scm_c_make_port_with_encoding (scm_t_bits tag, unsigned 
long mode_bits,
 {
   SCM ret;
   scm_t_port *entry;
+  scm_t_ptob_descriptor *ptob;
 
   entry = (scm_t_port *) scm_gc_calloc (sizeof (scm_t_port), "port");
-  ret = scm_cell (tag | mode_bits, (scm_t_bits)entry);
+  ptob = scm_c_port_type_ref (SCM_TC2PTOBNUM (tag));
+
+  ret = scm_words (tag | mode_bits, 3);
+  SCM_SET_CELL_WORD_1 (ret, (scm_t_bits) entry);
+  SCM_SET_CELL_WORD_2 (ret, (scm_t_bits) ptob);
+
+#if SCM_USE_PTHREAD_THREADS
+  scm_i_pthread_mutex_init (&entry->lock, scm_i_pthread_mutexattr_recursive);
+#endif
 
   entry->file_name = SCM_BOOL_F;
   entry->rw_active = SCM_PORT_NEITHER;
@@ -775,7 +819,8 @@ SCM_DEFINE (scm_port_mode, "port-mode", 1, 0, 0,
     strcpy (modes, "w");
   if (SCM_CELL_WORD_0 (port) & SCM_BUF0)
     strcat (modes, "0");
-  return scm_from_locale_string (modes);
+
+  return scm_from_latin1_string (modes);
 }
 #undef FUNC_NAME
 
@@ -797,7 +842,6 @@ SCM_DEFINE (scm_close_port, "close-port", 1, 0, 0,
            "descriptors.")
 #define FUNC_NAME s_scm_close_port
 {
-  size_t i;
   int rv;
 
   port = SCM_COERCE_OUTPORT (port);
@@ -805,9 +849,8 @@ SCM_DEFINE (scm_close_port, "close-port", 1, 0, 0,
   SCM_VALIDATE_PORT (1, port);
   if (SCM_CLOSEDP (port))
     return SCM_BOOL_F;
-  i = SCM_PTOBNUM (port);
-  if (scm_ptobs[i].close)
-    rv = (scm_ptobs[i].close) (port);
+  if (SCM_PORT_DESCRIPTOR (port)->close)
+    rv = SCM_PORT_DESCRIPTOR (port)->close (port);
   else
     rv = 0;
   scm_i_remove_port (port);
@@ -1363,7 +1406,7 @@ scm_fill_input (SCM port)
       if (pt->read_pos < pt->read_end)
        return *(pt->read_pos);
     }
-  return scm_ptobs[SCM_PTOBNUM (port)].fill_input (port);
+  return SCM_PORT_DESCRIPTOR (port)->fill_input (port);
 }
 
 
@@ -1376,7 +1419,7 @@ void
 scm_lfwrite (const char *ptr, size_t size, SCM port)
 {
   scm_t_port *pt = SCM_PTAB_ENTRY (port);
-  scm_t_ptob_descriptor *ptob = &scm_ptobs[SCM_PTOBNUM (port)];
+  scm_t_ptob_descriptor *ptob = SCM_PORT_DESCRIPTOR (port);
 
   if (pt->rw_active == SCM_PORT_READ)
     scm_end_input (port);
@@ -1454,7 +1497,7 @@ scm_c_read (SCM port, void *buffer, size_t size)
 
   pt = SCM_PTAB_ENTRY (port);
   if (pt->rw_active == SCM_PORT_WRITE)
-    scm_ptobs[SCM_PTOBNUM (port)].flush (port);
+    SCM_PORT_DESCRIPTOR (port)->flush (port);
 
   if (pt->rw_random)
     pt->rw_active = SCM_PORT_READ;
@@ -1566,7 +1609,7 @@ scm_c_write (SCM port, const void *ptr, size_t size)
   SCM_VALIDATE_OPOUTPORT (1, port);
 
   pt = SCM_PTAB_ENTRY (port);
-  ptob = &scm_ptobs[SCM_PTOBNUM (port)];
+  ptob = SCM_PORT_DESCRIPTOR (port);
 
   if (pt->rw_active == SCM_PORT_READ)
     scm_end_input (port);
@@ -1581,9 +1624,7 @@ scm_c_write (SCM port, const void *ptr, size_t size)
 void
 scm_flush (SCM port)
 {
-  long i = SCM_PTOBNUM (port);
-  assert (i >= 0);
-  (scm_ptobs[i].flush) (port);
+  SCM_PORT_DESCRIPTOR (port)->flush (port);
 }
 
 void
@@ -1603,7 +1644,7 @@ scm_end_input (SCM port)
   else
     offset = 0;
 
-  scm_ptobs[SCM_PTOBNUM (port)].end_input (port, offset);
+  SCM_PORT_DESCRIPTOR (port)->end_input (port, offset);
 }
 
 
@@ -1876,7 +1917,7 @@ SCM_DEFINE (scm_seek, "seek", 3, 0, 0,
 
   if (SCM_OPPORTP (fd_port))
     {
-      scm_t_ptob_descriptor *ptob = scm_ptobs + SCM_PTOBNUM (fd_port);
+      scm_t_ptob_descriptor *ptob = SCM_PORT_DESCRIPTOR (fd_port);
       off_t_or_off64_t off = scm_to_off_t_or_off64_t (offset);
       off_t_or_off64_t rv;
 
@@ -1971,7 +2012,7 @@ SCM_DEFINE (scm_truncate_file, "truncate-file", 1, 1, 0,
     {
       off_t_or_off64_t c_length = scm_to_off_t_or_off64_t (length);
       scm_t_port *pt = SCM_PTAB_ENTRY (object);
-      scm_t_ptob_descriptor *ptob = scm_ptobs + SCM_PTOBNUM (object);
+      scm_t_ptob_descriptor *ptob = SCM_PORT_DESCRIPTOR (object);
       
       if (!ptob->truncate)
        SCM_MISC_ERROR ("port is not truncatable", SCM_EOL);
diff --git a/libguile/ports.h b/libguile/ports.h
index f8bff35..2b72a70 100644
--- a/libguile/ports.h
+++ b/libguile/ports.h
@@ -26,7 +26,12 @@
 
 #include "libguile/__scm.h"
 
+#include <stdio.h>
+#include <string.h>
 #include <unistd.h>
+#include "libguile/gc.h"
+#include "libguile/tags.h"
+#include "libguile/error.h"
 #include "libguile/print.h"
 #include "libguile/struct.h"
 #include "libguile/threads.h"
@@ -48,6 +53,10 @@ typedef enum scm_t_port_rw_active {
 typedef struct 
 {
   SCM port;                    /* Link back to the port object.  */
+#if SCM_USE_PTHREAD_THREADS
+  scm_i_pthread_mutex_t lock;   /* A recursive lock for this port.  */
+#endif
+
   int revealed;                        /* 0 not revealed, > 1 revealed.
                                 * Revealed ports do not get GC'd.
                                 */
@@ -150,6 +159,7 @@ SCM_INTERNAL SCM scm_i_port_weak_set;
   SCM_SET_CELL_WORD_0 ((p), SCM_CELL_WORD_0 (p) & ~SCM_OPN)
 
 #define SCM_PTAB_ENTRY(x)         ((scm_t_port *) SCM_CELL_WORD_1 (x))
+#define SCM_PORT_DESCRIPTOR(port) ((scm_t_ptob_descriptor *) SCM_CELL_WORD_2 
(port))
 #define SCM_SETPTAB_ENTRY(x, ent)  (SCM_SET_CELL_WORD_1 ((x), (scm_t_bits) 
(ent)))
 #define SCM_STREAM(x)             (SCM_PTAB_ENTRY(x)->stream)
 #define SCM_SETSTREAM(x, s)        (SCM_PTAB_ENTRY(x)->stream = (scm_t_bits) 
(s))
@@ -196,19 +206,12 @@ typedef struct scm_t_ptob_descriptor
 #define SCM_TC2PTOBNUM(x) (0x0ff & ((x) >> 8))
 #define SCM_PTOBNUM(x) (SCM_TC2PTOBNUM (SCM_CELL_TYPE (x)))
 /* SCM_PTOBNAME can be 0 if name is missing */
-#define SCM_PTOBNAME(ptobnum) scm_ptobs[ptobnum].name
-
-
-
-/* Hey you!  Yes you, reading the header file!  We're going to deprecate
-   scm_ptobs in 2.2, so please don't write any new code that uses it.
-   Thanks.  */
-SCM_API scm_t_ptob_descriptor *scm_ptobs;
-SCM_API long scm_numptob;
+#define SCM_PTOBNAME(ptobnum) (scm_c_port_type_ref (ptobnum)->name)
 
-
-
-SCM_API SCM scm_markstream (SCM ptr);
+/* Port types, and their vtables.  */
+SCM_INTERNAL long scm_c_num_port_types (void);
+SCM_API scm_t_ptob_descriptor* scm_c_port_type_ref (long ptobnum);
+SCM_API long scm_c_port_type_add_x (scm_t_ptob_descriptor *desc);
 SCM_API scm_t_bits scm_make_port_type (char *name,
                                       int (*fill_input) (SCM port),
                                       void (*write) (SCM port, 
@@ -223,11 +226,10 @@ SCM_API void scm_set_port_print (scm_t_bits tc,
 SCM_API void scm_set_port_equalp (scm_t_bits tc, SCM (*equalp) (SCM, SCM));
 SCM_API void scm_set_port_close (scm_t_bits tc, int (*close) (SCM));
 
-SCM_API void scm_set_port_flush (scm_t_bits tc, 
-                                void (*flush) (SCM port));
+SCM_API void scm_set_port_flush (scm_t_bits tc, void (*flush) (SCM port));
 SCM_API void scm_set_port_end_input (scm_t_bits tc,
-                                    void (*end_input) (SCM port,
-                                                       int offset));
+                                     void (*end_input) (SCM port,
+                                                        int offset));
 SCM_API void scm_set_port_seek (scm_t_bits tc,
                                scm_t_off (*seek) (SCM port,
                                                   scm_t_off OFFSET,
@@ -236,9 +238,8 @@ SCM_API void scm_set_port_truncate (scm_t_bits tc,
                                    void (*truncate) (SCM port,
                                                      scm_t_off length));
 SCM_API void scm_set_port_input_waiting (scm_t_bits tc, int (*input_waiting) 
(SCM));
-SCM_API SCM scm_char_ready_p (SCM port);
-size_t scm_take_from_input_buffers (SCM port, char *dest, size_t read_len);
-SCM_API SCM scm_drain_input (SCM port);
+
+/* The input, output, error, and load ports.  */
 SCM_API SCM scm_current_input_port (void);
 SCM_API SCM scm_current_output_port (void);
 SCM_API SCM scm_current_error_port (void);
@@ -249,7 +250,14 @@ SCM_API SCM scm_set_current_error_port (SCM port);
 SCM_API void scm_dynwind_current_input_port (SCM port);
 SCM_API void scm_dynwind_current_output_port (SCM port);
 SCM_API void scm_dynwind_current_error_port (SCM port);
+SCM_INTERNAL void scm_i_dynwind_current_load_port (SCM port);
 
+/* Mode bits.  */
+SCM_INTERNAL long scm_i_mode_bits (SCM modes);
+SCM_API long scm_mode_bits (char *modes);
+SCM_API SCM scm_port_mode (SCM port);
+
+/* Low-level constructors.  */
 SCM_API SCM
 scm_c_make_port_with_encoding (scm_t_bits tag,
                                unsigned long mode_bits,
@@ -258,45 +266,77 @@ scm_c_make_port_with_encoding (scm_t_bits tag,
                                scm_t_bits stream);
 SCM_API SCM scm_c_make_port (scm_t_bits tag, unsigned long mode_bits,
                              scm_t_bits stream);
-
 SCM_API SCM scm_new_port_table_entry (scm_t_bits tag);
-SCM_API void scm_grow_port_cbuf (SCM port, size_t requested);
-SCM_API SCM scm_pt_size (void);
-SCM_API SCM scm_pt_member (SCM member);
-SCM_API void scm_port_non_buffer (scm_t_port *pt);
-SCM_API int scm_revealed_count (SCM port);
-SCM_API SCM scm_port_revealed (SCM port);
-SCM_API SCM scm_set_port_revealed_x (SCM port, SCM rcount);
-SCM_API long scm_mode_bits (char *modes);
-SCM_API SCM scm_port_mode (SCM port);
-SCM_API SCM scm_close_input_port (SCM port);
-SCM_API SCM scm_close_output_port (SCM port);
-SCM_API SCM scm_close_port (SCM port);
-SCM_API SCM scm_port_for_each (SCM proc);
-SCM_API void scm_c_port_for_each (void (*proc)(void *data, SCM p), void *data);
+
+/* Predicates.  */
+SCM_API SCM scm_port_p (SCM x);
 SCM_API SCM scm_input_port_p (SCM x);
 SCM_API SCM scm_output_port_p (SCM x);
-SCM_API SCM scm_port_p (SCM x);
 SCM_API SCM scm_port_closed_p (SCM port);
 SCM_API SCM scm_eof_object_p (SCM x);
-SCM_API SCM scm_force_output (SCM port);
-SCM_API SCM scm_flush_all_ports (void);
-SCM_API SCM scm_read_char (SCM port);
-SCM_API scm_t_wchar scm_getc (SCM port);
+
+/* Closing ports.  */
+SCM_API SCM scm_close_port (SCM port);
+SCM_API SCM scm_close_input_port (SCM port);
+SCM_API SCM scm_close_output_port (SCM port);
+
+/* Encoding characters to byte streams, and decoding byte streams to
+   characters.  */
+SCM_INTERNAL const char *scm_i_default_port_encoding (void);
+SCM_INTERNAL void scm_i_set_default_port_encoding (const char *);
+SCM_INTERNAL void scm_i_set_port_encoding_x (SCM port, const char *str);
+SCM_API SCM scm_port_encoding (SCM port);
+SCM_API SCM scm_set_port_encoding_x (SCM port, SCM encoding);
+SCM_INTERNAL scm_t_string_failed_conversion_handler 
scm_i_get_conversion_strategy (SCM port);
+SCM_INTERNAL void scm_i_set_conversion_strategy_x (SCM port, 
+                                                  
scm_t_string_failed_conversion_handler h);
+SCM_API SCM scm_port_conversion_strategy (SCM port);
+SCM_API SCM scm_set_port_conversion_strategy_x (SCM port, SCM behavior);
+
+/* Acquiring and releasing the port lock.  */
+SCM_INLINE int scm_c_lock_port (scm_t_port *entry);
+SCM_INLINE int scm_c_try_lock_port (scm_t_port *entry);
+SCM_INLINE int scm_c_unlock_port (scm_t_port *entry);
+
+/* Meta.  */
+SCM_API int scm_revealed_count (SCM port);
+SCM_API SCM scm_port_revealed (SCM port);
+SCM_API SCM scm_set_port_revealed_x (SCM port, SCM rcount);
+
+/* Input.  */
+SCM_INLINE int scm_get_byte_or_eof (SCM port);
+SCM_INLINE int scm_peek_byte_or_eof (SCM port);
 SCM_API size_t scm_c_read (SCM port, void *buffer, size_t size);
-SCM_API void scm_c_write (SCM port, const void *buffer, size_t size);
-SCM_API void scm_lfwrite (const char *ptr, size_t size, SCM port);
-SCM_INTERNAL void scm_lfwrite_substr (SCM str, size_t start, size_t end,
-                                     SCM port);
-SCM_API void scm_flush (SCM port);
-SCM_API void scm_end_input (SCM port);
-SCM_API int scm_fill_input (SCM port);
+SCM_API scm_t_wchar scm_getc (SCM port);
+SCM_API SCM scm_peek_char (SCM port);
+SCM_API SCM scm_read_char (SCM port);
+
+/* Pushback.  */
 SCM_INTERNAL void scm_unget_byte (int c, SCM port); 
 SCM_API void scm_ungetc (scm_t_wchar c, SCM port);
 SCM_API void scm_ungets (const char *s, int n, SCM port);
-SCM_API SCM scm_peek_char (SCM port);
 SCM_API SCM scm_unread_char (SCM cobj, SCM port);
 SCM_API SCM scm_unread_string (SCM str, SCM port);
+
+/* Manipulating the buffers.  */
+SCM_API void scm_port_non_buffer (scm_t_port *pt);
+SCM_API int scm_fill_input (SCM port);
+SCM_INTERNAL size_t scm_take_from_input_buffers (SCM port, char *dest, size_t 
read_len);
+SCM_API SCM scm_drain_input (SCM port);
+SCM_API void scm_end_input (SCM port);
+SCM_API SCM scm_force_output (SCM port);
+SCM_API void scm_flush (SCM port);
+
+/* Output.  */
+SCM_INLINE void scm_putc (char c, SCM port);
+SCM_INLINE void scm_puts (const char *str_data, SCM port);
+SCM_API void scm_c_write (SCM port, const void *buffer, size_t size);
+SCM_API void scm_lfwrite (const char *ptr, size_t size, SCM port);
+SCM_INTERNAL void scm_lfwrite_substr (SCM str, size_t start, size_t end,
+                                     SCM port);
+
+/* Querying and setting positions, and character availability.  */
+SCM_API SCM scm_char_ready_p (SCM port);
 SCM_API SCM scm_seek (SCM object, SCM offset, SCM whence);
 SCM_API SCM scm_truncate_file (SCM object, SCM length);
 SCM_API SCM scm_port_line (SCM port);
@@ -305,32 +345,120 @@ SCM_API SCM scm_port_column (SCM port);
 SCM_API SCM scm_set_port_column_x (SCM port, SCM line);
 SCM_API SCM scm_port_filename (SCM port);
 SCM_API SCM scm_set_port_filename_x (SCM port, SCM filename);
-SCM_INTERNAL const char *scm_i_default_port_encoding (void);
-SCM_INTERNAL void scm_i_set_default_port_encoding (const char *);
-SCM_INTERNAL void scm_i_set_port_encoding_x (SCM port, const char *str);
-SCM_API SCM scm_port_encoding (SCM port);
-SCM_API SCM scm_set_port_encoding_x (SCM port, SCM encoding);
-SCM_INTERNAL scm_t_string_failed_conversion_handler 
scm_i_get_conversion_strategy (SCM port);
-SCM_INTERNAL void scm_i_set_conversion_strategy_x (SCM port, 
-                                                  
scm_t_string_failed_conversion_handler h);
-SCM_API SCM scm_port_conversion_strategy (SCM port);
-SCM_API SCM scm_set_port_conversion_strategy_x (SCM port, SCM behavior);
+
+/* Implementation helpers for port printing functions.  */
 SCM_API int scm_port_print (SCM exp, SCM port, scm_print_state *);
 SCM_API void scm_print_port_mode (SCM exp, SCM port);
+
+/* Iterating over all ports.  */
+SCM_API SCM scm_port_for_each (SCM proc);
+SCM_API void scm_c_port_for_each (void (*proc)(void *data, SCM p), void *data);
+SCM_API SCM scm_flush_all_ports (void);
+
+/* Void ports.  */
 SCM_API SCM scm_void_port (char * mode_str);
 SCM_API SCM scm_sys_make_void_port (SCM mode);
+
+/* Initialization.  */
 SCM_INTERNAL void scm_init_ports (void);
 
-#ifdef GUILE_DEBUG
-SCM_API SCM scm_pt_size (void);
-SCM_API SCM scm_pt_member (SCM member);
-#endif /* GUILE_DEBUG */
 
-/* internal */
+/* Inline function implementations.  */
 
-SCM_INTERNAL long scm_i_mode_bits (SCM modes);
-SCM_INTERNAL void scm_i_dynwind_current_load_port (SCM port);
+#if SCM_CAN_INLINE || defined SCM_INLINE_C_IMPLEMENTING_INLINES
+SCM_INLINE_IMPLEMENTATION int
+scm_c_lock_port (scm_t_port *entry)
+{
+#if SCM_USE_PTHREAD_THREADS
+  return scm_i_pthread_mutex_lock (&entry->lock);
+#else
+  return 0;
+#endif
+}
+
+SCM_INLINE_IMPLEMENTATION int
+scm_c_try_lock_port (scm_t_port *entry)
+{
+#if SCM_USE_PTHREAD_THREADS
+  return scm_i_pthread_mutex_trylock (&entry->lock);
+#else
+  return 0;
+#endif
+}
+
+SCM_INLINE_IMPLEMENTATION int
+scm_c_unlock_port (scm_t_port *entry)
+{
+#if SCM_USE_PTHREAD_THREADS
+  return scm_i_pthread_mutex_unlock (&entry->lock);
+#else
+  return 0;
+#endif
+}
+
+SCM_INLINE_IMPLEMENTATION int
+scm_get_byte_or_eof (SCM port)
+{
+  int c;
+  scm_t_port *pt = SCM_PTAB_ENTRY (port);
+
+  if (pt->rw_active == SCM_PORT_WRITE)
+    /* may be marginally faster than calling scm_flush.  */
+    SCM_PORT_DESCRIPTOR (port)->flush (port);
 
+  if (pt->rw_random)
+    pt->rw_active = SCM_PORT_READ;
+
+  if (pt->read_pos >= pt->read_end)
+    {
+      if (SCM_UNLIKELY (scm_fill_input (port) == EOF))
+       return EOF;
+    }
+
+  c = *(pt->read_pos++);
+
+  return c;
+}
+
+/* Like `scm_get_byte_or_eof' but does not change PORT's `read_pos'.  */
+SCM_INLINE_IMPLEMENTATION int
+scm_peek_byte_or_eof (SCM port)
+{
+  int c;
+  scm_t_port *pt = SCM_PTAB_ENTRY (port);
+
+  if (pt->rw_active == SCM_PORT_WRITE)
+    /* may be marginally faster than calling scm_flush.  */
+    SCM_PORT_DESCRIPTOR (port)->flush (port);
+
+  if (pt->rw_random)
+    pt->rw_active = SCM_PORT_READ;
+
+  if (pt->read_pos >= pt->read_end)
+    {
+      if (SCM_UNLIKELY (scm_fill_input (port) == EOF))
+       return EOF;
+    }
+
+  c = *pt->read_pos;
+
+  return c;
+}
+
+SCM_INLINE_IMPLEMENTATION void
+scm_putc (char c, SCM port)
+{
+  SCM_ASSERT_TYPE (SCM_OPOUTPORTP (port), port, 0, NULL, "output port");
+  scm_lfwrite (&c, 1, port);
+}
+
+SCM_INLINE_IMPLEMENTATION void
+scm_puts (const char *s, SCM port)
+{
+  SCM_ASSERT_TYPE (SCM_OPOUTPORTP (port), port, 0, NULL, "output port");
+  scm_lfwrite (s, strlen (s), port);
+}
+#endif  /* SCM_CAN_INLINE || defined SCM_INLINE_C_IMPLEMENTING_INLINES */
 
 #endif  /* SCM_PORTS_H */
 
diff --git a/libguile/print.c b/libguile/print.c
index 8846cd3..5ee48ee 100644
--- a/libguile/print.c
+++ b/libguile/print.c
@@ -690,10 +690,8 @@ iprin1 (SCM exp, SCM port, scm_print_state *pstate)
          break;
        case scm_tc7_port:
          {
-           register long i = SCM_PTOBNUM (exp);
-           if (i < scm_numptob
-               && scm_ptobs[i].print
-               && (scm_ptobs[i].print) (exp, port, pstate))
+           scm_t_ptob_descriptor *ptob = SCM_PORT_DESCRIPTOR (exp);
+           if (ptob->print && ptob->print (exp, port, pstate))
              break;
            goto punk;
          }
@@ -1469,7 +1467,7 @@ static int
 port_with_ps_print (SCM obj, SCM port, scm_print_state *pstate)
 {
   obj = SCM_PORT_WITH_PS_PORT (obj);
-  return scm_ptobs[SCM_PTOBNUM (obj)].print (obj, port, pstate);
+  return SCM_PORT_DESCRIPTOR (obj)->print (obj, port, pstate);
 }
 
 SCM


hooks/post-receive
-- 
GNU Guile



reply via email to

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