mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-05-20 19:50:24 +02:00
ports: avoid adding port table entries and finalizers if possible
* libguile/ports.h (scm_t_port_type_flags, scm_t_ptob_descriptor): Add flags to ptob descriptors. * libguile/ports.c (scm_set_port_flush): Set the SCM_PORT_TYPE_HAS_FLUSH flag here. (scm_c_make_port_with_encoding): Only add ports to the table if SCM_PORT_TYPE_HAS_FLUSH is set. Only add finalizers to ports if there is a free function. (scm_close_port): Inline scm_i_remove_port here. Only remove from the weak set if SCM_PORT_TYPE_HAS_FLUSH is set. (scm_set_port_revealed_x): Add a comment.
This commit is contained in:
parent
6c98257f2e
commit
03a2eeb0cc
2 changed files with 37 additions and 33 deletions
|
@ -250,7 +250,9 @@ scm_set_port_close (scm_t_bits tc, int (*close) (SCM))
|
|||
void
|
||||
scm_set_port_flush (scm_t_bits tc, void (*flush) (SCM port))
|
||||
{
|
||||
scm_c_port_type_ref (SCM_TC2PTOBNUM (tc))->flush = flush;
|
||||
scm_t_ptob_descriptor *ptob = scm_c_port_type_ref (SCM_TC2PTOBNUM (tc));
|
||||
ptob->flush = flush;
|
||||
ptob->flags |= SCM_PORT_TYPE_HAS_FLUSH;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -612,11 +614,11 @@ scm_c_make_port_with_encoding (scm_t_bits tag, unsigned long mode_bits,
|
|||
entry->ilseq_handler = handler;
|
||||
entry->iconv_descriptors = NULL;
|
||||
|
||||
scm_weak_set_add_x (scm_i_port_weak_set, ret);
|
||||
if (SCM_PORT_DESCRIPTOR (ret)->flags & SCM_PORT_TYPE_HAS_FLUSH)
|
||||
scm_weak_set_add_x (scm_i_port_weak_set, ret);
|
||||
|
||||
/* For each new port, register a finalizer so that it port type's free
|
||||
function can be invoked eventually. */
|
||||
register_finalizer_for_port (ret);
|
||||
if (SCM_PORT_DESCRIPTOR (ret)->free)
|
||||
register_finalizer_for_port (ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -636,33 +638,6 @@ scm_new_port_table_entry (scm_t_bits tag)
|
|||
return scm_c_make_port (tag, 0, 0);
|
||||
}
|
||||
|
||||
/* Remove a port from the table and destroy it. */
|
||||
|
||||
static void close_iconv_descriptors (scm_t_iconv_descriptors *id);
|
||||
|
||||
static void
|
||||
scm_i_remove_port (SCM port)
|
||||
#define FUNC_NAME "scm_remove_port"
|
||||
{
|
||||
scm_t_port *p;
|
||||
|
||||
p = SCM_PTAB_ENTRY (port);
|
||||
scm_port_non_buffer (p);
|
||||
SCM_SETPTAB_ENTRY (port, 0);
|
||||
scm_weak_set_remove_x (scm_i_port_weak_set, port);
|
||||
|
||||
p->putback_buf = NULL;
|
||||
p->putback_buf_size = 0;
|
||||
|
||||
if (p->iconv_descriptors)
|
||||
{
|
||||
close_iconv_descriptors (p->iconv_descriptors);
|
||||
p->iconv_descriptors = NULL;
|
||||
}
|
||||
}
|
||||
#undef FUNC_NAME
|
||||
|
||||
|
||||
|
||||
|
||||
/* Predicates. */
|
||||
|
@ -727,6 +702,8 @@ SCM_DEFINE (scm_eof_object_p, "eof-object?", 1, 0, 0,
|
|||
|
||||
/* Closing ports. */
|
||||
|
||||
static void close_iconv_descriptors (scm_t_iconv_descriptors *id);
|
||||
|
||||
/* scm_close_port
|
||||
* Call the close operation on a port object.
|
||||
* see also scm_close.
|
||||
|
@ -741,6 +718,7 @@ SCM_DEFINE (scm_close_port, "close-port", 1, 0, 0,
|
|||
"descriptors.")
|
||||
#define FUNC_NAME s_scm_close_port
|
||||
{
|
||||
scm_t_port *p;
|
||||
int rv;
|
||||
|
||||
port = SCM_COERCE_OUTPORT (port);
|
||||
|
@ -752,8 +730,26 @@ SCM_DEFINE (scm_close_port, "close-port", 1, 0, 0,
|
|||
rv = SCM_PORT_DESCRIPTOR (port)->close (port);
|
||||
else
|
||||
rv = 0;
|
||||
scm_i_remove_port (port);
|
||||
|
||||
p = SCM_PTAB_ENTRY (port);
|
||||
|
||||
scm_port_non_buffer (p);
|
||||
SCM_SETPTAB_ENTRY (port, 0);
|
||||
|
||||
if (SCM_PORT_DESCRIPTOR (port)->flags & SCM_PORT_TYPE_HAS_FLUSH)
|
||||
scm_weak_set_remove_x (scm_i_port_weak_set, port);
|
||||
|
||||
p->putback_buf = NULL;
|
||||
p->putback_buf_size = 0;
|
||||
|
||||
if (p->iconv_descriptors)
|
||||
{
|
||||
close_iconv_descriptors (p->iconv_descriptors);
|
||||
p->iconv_descriptors = NULL;
|
||||
}
|
||||
|
||||
SCM_CLR_PORT_OPEN_FLAG (port);
|
||||
|
||||
return scm_from_bool (rv >= 0);
|
||||
}
|
||||
#undef FUNC_NAME
|
||||
|
@ -1254,6 +1250,9 @@ SCM_DEFINE (scm_set_port_revealed_x, "set-port-revealed!", 2, 0, 0,
|
|||
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);
|
||||
|
|
|
@ -191,6 +191,10 @@ SCM_INTERNAL SCM scm_i_port_weak_set;
|
|||
|
||||
|
||||
|
||||
typedef enum scm_t_port_type_flags {
|
||||
SCM_PORT_TYPE_HAS_FLUSH = 1 << 0
|
||||
} scm_t_port_type_flags;
|
||||
|
||||
/* port-type description. */
|
||||
typedef struct scm_t_ptob_descriptor
|
||||
{
|
||||
|
@ -211,6 +215,7 @@ typedef struct scm_t_ptob_descriptor
|
|||
scm_t_off (*seek) (SCM port, scm_t_off OFFSET, int WHENCE);
|
||||
void (*truncate) (SCM port, scm_t_off length);
|
||||
|
||||
unsigned flags;
|
||||
} scm_t_ptob_descriptor;
|
||||
|
||||
#define SCM_TC2PTOBNUM(x) (0x0ff & ((x) >> 8))
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue