diff options
author | Andy Wingo <wingo@pobox.com> | 2012-02-19 12:34:20 +0100 |
---|---|---|
committer | Andy Wingo <wingo@pobox.com> | 2012-02-19 13:30:30 +0100 |
commit | 3753e22736feb56ad22ec802bbad16e080066789 (patch) | |
tree | b5143e8bf15dd1c62ce32a7131975c006f44ce1f | |
parent | bc1bc9e32088958c1b381f9ec0056e40340433a1 (diff) | |
download | guile-3753e22736feb56ad22ec802bbad16e080066789.tar.gz |
move revealed-count mechanism to fports.c
* 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.
-rw-r--r-- | libguile/fports.c | 100 | ||||
-rw-r--r-- | libguile/fports.h | 14 | ||||
-rw-r--r-- | libguile/init.c | 3 | ||||
-rw-r--r-- | libguile/ports.c | 97 | ||||
-rw-r--r-- | libguile/ports.h | 11 |
5 files changed, 120 insertions, 105 deletions
diff --git a/libguile/fports.c b/libguile/fports.c index bb998e7c4..9fcfbcb1f 100644 --- a/libguile/fports.c +++ b/libguile/fports.c @@ -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 } + + + +/* 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 + + static int fport_print (SCM exp, SCM port, scm_print_state *pstate SCM_UNUSED) diff --git a/libguile/fports.h b/libguile/fports.h index 32b6a5947..4094f14cd 100644 --- a/libguile/fports.h +++ b/libguile/fports.h @@ -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); + + +/* 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); + + SCM_INTERNAL void scm_init_fports (void); /* internal functions */ diff --git a/libguile/init.c b/libguile/init.c index 35fbedb8b..7dec116fa 100644 --- a/libguile/init.c +++ b/libguile/init.c @@ -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; } diff --git a/libguile/ports.c b/libguile/ports.c index 414ea9400..a989088f3 100644 --- a/libguile/ports.c +++ b/libguile/ports.c @@ -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) -/* 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 - - - - /* Input. */ int diff --git a/libguile/ports.h b/libguile/ports.h index b44ec66a9..c42b501fd 100644 --- a/libguile/ports.h +++ b/libguile/ports.h @@ -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); |