move revealed-count mechanism to fports.c
authorAndy Wingo <wingo@pobox.com>
Sun, 19 Feb 2012 11:34:20 +0000 (12:34 +0100)
committerAndy Wingo <wingo@pobox.com>
Sun, 19 Feb 2012 12:30:30 +0000 (13:30 +0100)
* libguile/fports.c (scm_revealed_count, scm_port_revealed)
  (scm_set_port_revealed_x, scm_adjust_port_revealed_x): Move these APIs
  here, and only operate on fports.  To keep revealed ports alive, now
  we will just keep them in a data structure that the GC knows about --
  a static list.

* libguile/fports.h: Add revealed count to scm_t_fport, and move decls
  of revealed-count functions here.

* libguile/ports.h:
* libguile/ports.c: Adapt to change.  Remove SCM_REVEALED and
  SCM_SETREVEALED; since they only apply to fports now, keeping them
  around would be inviting type errors.
  (finalize_port): We don't need to worry about resuscitating ports
  here.

* libguile/init.c: Use the scm_set_port_revealed_x function to set the
  revealed counts on stream ports.

libguile/fports.c
libguile/fports.h
libguile/init.c
libguile/ports.c
libguile/ports.h

index bb998e7..9fcfbcb 100644 (file)
@@ -1,5 +1,5 @@
 /* Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
- *   2004, 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
+ *   2004, 2006, 2007, 2008, 2009, 2010, 2011, 2012 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
@@ -633,6 +633,104 @@ fport_input_waiting (SCM port)
 #endif
 }
 
+
+\f
+
+/* Revealed counts --- an oddity inherited from SCSH.  */
+
+#define SCM_REVEALED(x) (SCM_FSTREAM(x)->revealed)
+
+static SCM revealed_ports = SCM_EOL;
+static scm_i_pthread_mutex_t revealed_lock = SCM_I_PTHREAD_MUTEX_INITIALIZER;
+SCM_PTHREAD_ATFORK_LOCK_STATIC_MUTEX (revealed_lock);
+
+/* Find a port in the table and return its revealed count.
+   Also used by the garbage collector.
+ */
+int
+scm_revealed_count (SCM port)
+{
+  int ret;
+
+  scm_i_pthread_mutex_lock (&revealed_lock);
+  ret = SCM_REVEALED (port);
+  scm_i_pthread_mutex_unlock (&revealed_lock);
+
+  return ret;
+}
+
+SCM_DEFINE (scm_port_revealed, "port-revealed", 1, 0, 0,
+           (SCM port),
+           "Return the revealed count for @var{port}.")
+#define FUNC_NAME s_scm_port_revealed
+{
+  port = SCM_COERCE_OUTPORT (port);
+  SCM_VALIDATE_OPFPORT (1, port);
+  return scm_from_int (scm_revealed_count (port));
+}
+#undef FUNC_NAME
+
+/* Set the revealed count for a port.  */
+SCM_DEFINE (scm_set_port_revealed_x, "set-port-revealed!", 2, 0, 0,
+           (SCM port, SCM rcount),
+           "Sets the revealed count for a port to a given value.\n"
+           "The return value is unspecified.")
+#define FUNC_NAME s_scm_set_port_revealed_x
+{
+  int r, prev;
+
+  port = SCM_COERCE_OUTPORT (port);
+  SCM_VALIDATE_OPFPORT (1, port);
+
+  r = scm_to_int (rcount);
+
+  scm_i_pthread_mutex_lock (&revealed_lock);
+
+  prev = SCM_REVEALED (port);
+  SCM_REVEALED (port) = r;
+
+  if (r && !prev)
+    revealed_ports = scm_cons (port, revealed_ports);
+  else if (prev && !r)
+    revealed_ports = scm_delq_x (port, revealed_ports);
+
+  scm_i_pthread_mutex_unlock (&revealed_lock);
+
+  return SCM_UNSPECIFIED;
+}
+#undef FUNC_NAME
+
+/* Set the revealed count for a port.  */
+SCM_DEFINE (scm_adjust_port_revealed_x, "adjust-port-revealed!", 2, 0, 0,
+           (SCM port, SCM addend),
+           "Add @var{addend} to the revealed count of @var{port}.\n"
+           "The return value is unspecified.")
+#define FUNC_NAME s_scm_adjust_port_revealed_x
+{
+  int a;
+
+  port = SCM_COERCE_OUTPORT (port);
+  SCM_VALIDATE_OPFPORT (1, port);
+
+  a = scm_to_int (addend);
+  if (!a)
+    return SCM_UNSPECIFIED;
+
+  scm_i_pthread_mutex_lock (&revealed_lock);
+
+  SCM_REVEALED (port) += a;
+  if (SCM_REVEALED (port) == a)
+    revealed_ports = scm_cons (port, revealed_ports);
+  else if (!SCM_REVEALED (port))
+    revealed_ports = scm_delq_x (port, revealed_ports);
+
+  scm_i_pthread_mutex_unlock (&revealed_lock);
+
+  return SCM_UNSPECIFIED;
+}
+#undef FUNC_NAME
+
+
 \f
 static int 
 fport_print (SCM exp, SCM port, scm_print_state *pstate SCM_UNUSED)
index 32b6a59..4094f14 100644 (file)
@@ -3,7 +3,7 @@
 #ifndef SCM_FPORTS_H
 #define SCM_FPORTS_H
 
-/* Copyright (C) 1995,1996,1997,1998,1999,2000,2001, 2006, 2008, 2009, 2011 Free Software Foundation, Inc.
+/* Copyright (C) 1995,1996,1997,1998,1999,2000,2001, 2006, 2008, 2009, 2011, 2012 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
@@ -32,6 +32,9 @@
 /* struct allocated for each buffered FPORT.  */
 typedef struct scm_t_fport {
   int fdes;                    /* file descriptor.  */
+  int revealed;                        /* 0 not revealed, > 1 revealed.
+                                * Revealed ports do not get GC'd.
+                                */
 } scm_t_fport;
 
 SCM_API scm_t_bits scm_tc16_fport;
@@ -54,6 +57,15 @@ SCM_API void scm_evict_ports (int fd);
 SCM_API SCM scm_open_file (SCM filename, SCM modes);
 SCM_API SCM scm_fdes_to_port (int fdes, char *mode, SCM name);
 SCM_API SCM scm_file_port_p (SCM obj);
+
+\f
+/* Revealed counts.  */
+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 SCM scm_adjust_port_revealed_x (SCM port, SCM addend);
+
+\f
 SCM_INTERNAL void scm_init_fports (void);
 
 /* internal functions */
index 35fbedb..7dec116 100644 (file)
@@ -165,8 +165,7 @@ stream_body (void *data)
 {
   stream_body_data *body_data = (stream_body_data *) data;
   SCM port = scm_fdes_to_port (body_data->fdes, body_data->mode, SCM_BOOL_F);
-
-  SCM_REVEALED (port) = 1;
+  scm_set_port_revealed_x (port, SCM_INUM1);
   return port;
 }
 
index 414ea94..a989088 100644 (file)
@@ -578,23 +578,17 @@ finalize_port (GC_PTR ptr, GC_PTR data)
 
   if (SCM_OPENP (port))
     {
-      if (SCM_REVEALED (port) > 0)
-       /* Keep "revealed" ports alive and re-register a finalizer.  */
-       register_finalizer_for_port (port);
-      else
-       {
-          struct do_free_data data;
+      struct do_free_data data;
 
-         SCM_CLR_PORT_OPEN_FLAG (port);
+      SCM_CLR_PORT_OPEN_FLAG (port);
 
-          data.ptob = SCM_PORT_DESCRIPTOR (port);
-          data.port = port;
+      data.ptob = SCM_PORT_DESCRIPTOR (port);
+      data.port = port;
 
-          scm_internal_catch (SCM_BOOL_T, do_free, &data,
-                              scm_handle_by_message_noexit, NULL);
+      scm_internal_catch (SCM_BOOL_T, do_free, &data,
+                          scm_handle_by_message_noexit, NULL);
 
-         scm_gc_ports_collected++;
-       }
+      scm_gc_ports_collected++;
     }
 }
 
@@ -1235,83 +1229,6 @@ scm_dynwind_lock_port (SCM port)
 
 \f
 
-/* Revealed counts --- an oddity inherited from SCSH.  */
-
-/* Find a port in the table and return its revealed count.
-   Also used by the garbage collector.
- */
-int
-scm_revealed_count (SCM port)
-{
-  scm_i_pthread_mutex_t *lock;
-  int ret;
-  
-  scm_c_lock_port (port, &lock);
-  ret = SCM_REVEALED (port);
-  if (lock)
-    scm_i_pthread_mutex_unlock (lock);
-  
-  return ret;
-}
-
-SCM_DEFINE (scm_port_revealed, "port-revealed", 1, 0, 0,
-           (SCM port),
-           "Return the revealed count for @var{port}.")
-#define FUNC_NAME s_scm_port_revealed
-{
-  port = SCM_COERCE_OUTPORT (port);
-  SCM_VALIDATE_OPENPORT (1, port);
-  return scm_from_int (scm_revealed_count (port));
-}
-#undef FUNC_NAME
-
-/* Set the revealed count for a port.  */
-SCM_DEFINE (scm_set_port_revealed_x, "set-port-revealed!", 2, 0, 0,
-           (SCM port, SCM rcount),
-           "Sets the revealed count for a port to a given value.\n"
-           "The return value is unspecified.")
-#define FUNC_NAME s_scm_set_port_revealed_x
-{
-  int r;
-  scm_i_pthread_mutex_t *lock;
-  
-  /* FIXME: It doesn't make sense to manipulate revealed counts on ports
-     without a free function.  */
-
-  port = SCM_COERCE_OUTPORT (port);
-  SCM_VALIDATE_OPENPORT (1, port);
-  r = scm_to_int (rcount);
-  scm_c_lock_port (port, &lock);
-  SCM_REVEALED (port) = r;
-  if (lock)
-    scm_i_pthread_mutex_unlock (lock);
-  return SCM_UNSPECIFIED;
-}
-#undef FUNC_NAME
-
-/* Set the revealed count for a port.  */
-SCM_DEFINE (scm_adjust_port_revealed_x, "adjust-port-revealed!", 2, 0, 0,
-           (SCM port, SCM addend),
-           "Add @var{addend} to the revealed count of @var{port}.\n"
-           "The return value is unspecified.")
-#define FUNC_NAME s_scm_adjust_port_revealed_x
-{
-  scm_i_pthread_mutex_t *lock;
-  int a;
-  port = SCM_COERCE_OUTPORT (port);
-  SCM_VALIDATE_OPENPORT (1, port);
-  a = scm_to_int (addend);
-  scm_c_lock_port (port, &lock);
-  SCM_REVEALED (port) += a;
-  if (lock)
-    scm_i_pthread_mutex_unlock (lock);
-  return SCM_UNSPECIFIED;
-}
-#undef FUNC_NAME
-
-
-\f
-
 /* Input.  */
 
 int
index b44ec66..c42b501 100644 (file)
@@ -69,9 +69,6 @@ typedef struct
   SCM port;                    /* Link back to the port object.  */
   scm_i_pthread_mutex_t *lock;  /* A recursive lock for this port.  */
 
-  int revealed;                        /* 0 not revealed, > 1 revealed.
-                                * Revealed ports do not get GC'd.
-                                */
   /* data for the underlying port implementation as a raw C value. */
   scm_t_bits stream;
 
@@ -177,8 +174,6 @@ SCM_INTERNAL SCM scm_i_port_weak_set;
 #define SCM_SET_FILENAME(x, n)    (SCM_PTAB_ENTRY(x)->file_name = (n))
 #define SCM_LINUM(x)              (SCM_PTAB_ENTRY(x)->line_number)
 #define SCM_COL(x)                (SCM_PTAB_ENTRY(x)->column_number)
-#define SCM_REVEALED(x)           (SCM_PTAB_ENTRY(x)->revealed)
-#define SCM_SETREVEALED(x, s)      (SCM_PTAB_ENTRY(x)->revealed = (s))
 
 #define SCM_INCLINE(port)      do {SCM_LINUM (port) += 1; SCM_COL (port) = 0;} while (0)
 #define SCM_ZEROCOL(port)      do {SCM_COL (port) = 0;} while (0)
@@ -316,12 +311,6 @@ SCM_API void scm_dynwind_lock_port (SCM port);
 SCM_INLINE int scm_c_lock_port (SCM port, scm_i_pthread_mutex_t **lock);
 SCM_INLINE int scm_c_try_lock_port (SCM port, scm_i_pthread_mutex_t **lock);
 
-/* Revealed counts.  */
-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 SCM scm_adjust_port_revealed_x (SCM port, SCM addend);
-
 /* Input.  */
 SCM_API int scm_get_byte_or_eof (SCM port);
 SCM_INLINE int scm_get_byte_or_eof_unlocked (SCM port);