1
Fork 0
mirror of https://git.savannah.gnu.org/git/guile.git synced 2025-05-20 11:40:18 +02:00

* ports.c (scm_port_for_each): Make a snapshot of the port table

before iterating over it.  The table might change while the user
code is running.  With the snapshot, the user can depend on the
fact that each port that was open at teh start of the iteration is
encountered exactly once.  (ice-9 popen) depends on this.
This commit is contained in:
Marius Vollmer 2001-02-08 18:44:34 +00:00
parent 6a721afbc8
commit fdfe6305a5

View file

@ -697,15 +697,32 @@ SCM_DEFINE (scm_port_for_each, "port-for-each", 1, 0, 0,
#define FUNC_NAME s_scm_port_for_each
{
int i;
SCM ports;
SCM_VALIDATE_PROC (1, proc);
/* when pre-emptive multithreading is supported, access to the port
table will need to be controlled by a mutex. */
/* Even without pre-emptive multithreading, running arbitrary code
while scanning the port table is unsafe because the port table
can change arbitrarily (from a GC, for example). So we build a
list in advance while blocking the GC. -mvo */
SCM_DEFER_INTS;
scm_block_gc++;
ports = SCM_EOL;
for (i = 0; i < scm_port_table_size; i++)
ports = scm_cons (scm_port_table[i]->port, ports);
scm_block_gc--;
SCM_ALLOW_INTS;
while (ports != SCM_EOL)
{
scm_apply (proc, scm_cons (scm_port_table[i]->port, SCM_EOL), SCM_EOL);
scm_apply (proc, scm_cons (SCM_CAR (ports), SCM_EOL), SCM_EOL);
ports = SCM_CDR (ports);
}
return SCM_UNSPECIFIED;
}
#undef FUNC_NAME