mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-05-20 03:30:27 +02:00
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.
This commit is contained in:
parent
bc1bc9e320
commit
3753e22736
5 changed files with 120 additions and 105 deletions
|
@ -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)
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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++;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1233,83 +1227,6 @@ scm_dynwind_lock_port (SCM port)
|
|||
#undef FUNC_NAME
|
||||
|
||||
|
||||
|
||||
|
||||
/* 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. */
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue