1
Fork 0
mirror of https://git.savannah.gnu.org/git/guile.git synced 2025-04-30 03:40:34 +02:00

* ports.c, ports.h (scm_i_port_table_mutex): New mutex.

* fports.c (scm_evict_ports): Lock/unlock scm_i_port_table_mutex.

* ports.c (scm_close_port, scm_flush_all_ports): Ditto.

* ioext.c (scm_fdes_to_ports): Ditto.

* vports.c (scm_make_soft_port): Changed SCM_DEFER/ALLOW_INTS into
lock/unlock scm_i_port_table_mutex.

* strports.c (scm_mkstrport): Ditto.

* ports.c (scm_void_port, scm_port_for_each): Ditto.

* fports.c (scm_fdes_to_port): Ditto.
This commit is contained in:
Mikael Djurfeldt 2003-04-24 16:02:04 +00:00
parent 359aab2498
commit b9ad392e86
7 changed files with 53 additions and 19 deletions

View file

@ -1,3 +1,22 @@
2003-04-24 Mikael Djurfeldt <mdj@kvast.blakulla.net>
* ports.c, ports.h (scm_i_port_table_mutex): New mutex.
* fports.c (scm_evict_ports): Lock/unlock scm_i_port_table_mutex.
* ports.c (scm_close_port, scm_flush_all_ports): Ditto.
* ioext.c (scm_fdes_to_ports): Ditto.
* vports.c (scm_make_soft_port): Changed SCM_DEFER/ALLOW_INTS into
lock/unlock scm_i_port_table_mutex.
* strports.c (scm_mkstrport): Ditto.
* ports.c (scm_void_port, scm_port_for_each): Ditto.
* fports.c (scm_fdes_to_port): Ditto.
2003-04-23 Dirk Herrmann <D.Herrmann@tu-bs.de> 2003-04-23 Dirk Herrmann <D.Herrmann@tu-bs.de>
This set of patches contains no functional changes, only debatable This set of patches contains no functional changes, only debatable

View file

@ -1,4 +1,4 @@
/* Copyright (C) 1995,1996,1997,1998,1999,2000,2001, 2002 Free Software Foundation, Inc. /* Copyright (C) 1995,1996,1997,1998,1999,2000,2001, 2002, 2003 Free Software Foundation, Inc.
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public
@ -199,6 +199,8 @@ scm_evict_ports (int fd)
{ {
long i; long i;
scm_mutex_lock (&scm_i_port_table_mutex);
for (i = 0; i < scm_i_port_table_size; i++) for (i = 0; i < scm_i_port_table_size; i++)
{ {
SCM port = scm_i_port_table[i]->port; SCM port = scm_i_port_table[i]->port;
@ -216,6 +218,8 @@ scm_evict_ports (int fd)
} }
} }
} }
scm_mutex_unlock (&scm_i_port_table_mutex);
} }
@ -415,7 +419,7 @@ scm_fdes_to_port (int fdes, char *mode, SCM name)
SCM_MISC_ERROR ("requested file mode not available on fdes", SCM_EOL); SCM_MISC_ERROR ("requested file mode not available on fdes", SCM_EOL);
} }
SCM_DEFER_INTS; scm_mutex_lock (&scm_i_port_table_mutex);
port = scm_new_port_table_entry (scm_tc16_fport); port = scm_new_port_table_entry (scm_tc16_fport);
SCM_SET_CELL_TYPE(port, scm_tc16_fport | mode_bits); SCM_SET_CELL_TYPE(port, scm_tc16_fport | mode_bits);
@ -433,7 +437,7 @@ scm_fdes_to_port (int fdes, char *mode, SCM name)
scm_fport_buffer_add (port, -1, -1); scm_fport_buffer_add (port, -1, -1);
} }
SCM_SET_FILENAME (port, name); SCM_SET_FILENAME (port, name);
SCM_ALLOW_INTS; scm_mutex_unlock (&scm_i_port_table_mutex);
return port; return port;
} }
#undef FUNC_NAME #undef FUNC_NAME

View file

@ -1,4 +1,4 @@
/* Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc. /* Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2003 Free Software Foundation, Inc.
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public
@ -282,12 +282,14 @@ SCM_DEFINE (scm_fdes_to_ports, "fdes->ports", 1, 0, 0,
SCM_VALIDATE_INUM_COPY (1, fd, int_fd); SCM_VALIDATE_INUM_COPY (1, fd, int_fd);
scm_mutex_lock (&scm_i_port_table_mutex);
for (i = 0; i < scm_i_port_table_size; i++) for (i = 0; i < scm_i_port_table_size; i++)
{ {
if (SCM_OPFPORTP (scm_i_port_table[i]->port) if (SCM_OPFPORTP (scm_i_port_table[i]->port)
&& ((scm_t_fport *) scm_i_port_table[i]->stream)->fdes == int_fd) && ((scm_t_fport *) scm_i_port_table[i]->stream)->fdes == int_fd)
result = scm_cons (scm_i_port_table[i]->port, result); result = scm_cons (scm_i_port_table[i]->port, result);
} }
scm_mutex_unlock (&scm_i_port_table_mutex);
return result; return result;
} }
#undef FUNC_NAME #undef FUNC_NAME

View file

@ -1,4 +1,4 @@
/* Copyright (C) 1995,1996,1997,1998,1999,2000,2001 Free Software Foundation, Inc. /* Copyright (C) 1995,1996,1997,1998,1999,2000,2001, 2003 Free Software Foundation, Inc.
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public
@ -431,6 +431,9 @@ scm_t_port **scm_i_port_table;
long scm_i_port_table_size = 0; /* Number of ports in scm_i_port_table. */ long scm_i_port_table_size = 0; /* Number of ports in scm_i_port_table. */
long scm_i_port_table_room = 20; /* Size of the array. */ long scm_i_port_table_room = 20; /* Size of the array. */
SCM_GLOBAL_MUTEX (scm_i_port_table_mutex);
/* This function is not and should not be thread safe. */
SCM SCM
scm_new_port_table_entry (scm_t_bits tag) scm_new_port_table_entry (scm_t_bits tag)
@ -487,6 +490,9 @@ scm_add_to_port_table (SCM port)
/* Remove a port from the table and destroy it. */ /* Remove a port from the table and destroy it. */
/* This function is not and should not be thread safe. */
void void
scm_remove_from_port_table (SCM port) scm_remove_from_port_table (SCM port)
#define FUNC_NAME "scm_remove_from_port_table" #define FUNC_NAME "scm_remove_from_port_table"
@ -679,7 +685,9 @@ SCM_DEFINE (scm_close_port, "close-port", 1, 0, 0,
rv = (scm_ptobs[i].close) (port); rv = (scm_ptobs[i].close) (port);
else else
rv = 0; rv = 0;
scm_mutex_lock (&scm_i_port_table_mutex);
scm_remove_from_port_table (port); scm_remove_from_port_table (port);
scm_mutex_unlock (&scm_i_port_table_mutex);
SCM_CLR_PORT_OPEN_FLAG (port); SCM_CLR_PORT_OPEN_FLAG (port);
return SCM_BOOL (rv >= 0); return SCM_BOOL (rv >= 0);
} }
@ -731,21 +739,18 @@ SCM_DEFINE (scm_port_for_each, "port-for-each", 1, 0, 0,
SCM_VALIDATE_PROC (1, proc); 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 /* Even without pre-emptive multithreading, running arbitrary code
while scanning the port table is unsafe because the port table while scanning the port table is unsafe because the port table
can change arbitrarily (from a GC, for example). So we build a can change arbitrarily (from a GC, for example). So we build a
list in advance while blocking the GC. -mvo */ list in advance while blocking the GC. -mvo */
SCM_DEFER_INTS; scm_mutex_lock (&scm_i_port_table_mutex);
scm_block_gc++; scm_block_gc++;
ports = SCM_EOL; ports = SCM_EOL;
for (i = 0; i < scm_i_port_table_size; i++) for (i = 0; i < scm_i_port_table_size; i++)
ports = scm_cons (scm_i_port_table[i]->port, ports); ports = scm_cons (scm_i_port_table[i]->port, ports);
scm_block_gc--; scm_block_gc--;
SCM_ALLOW_INTS; scm_mutex_unlock (&scm_i_port_table_mutex);
while (ports != SCM_EOL) while (ports != SCM_EOL)
{ {
@ -845,11 +850,13 @@ SCM_DEFINE (scm_flush_all_ports, "flush-all-ports", 0, 0, 0,
{ {
size_t i; size_t i;
scm_mutex_lock (&scm_i_port_table_mutex);
for (i = 0; i < scm_i_port_table_size; i++) for (i = 0; i < scm_i_port_table_size; i++)
{ {
if (SCM_OPOUTPORTP (scm_i_port_table[i]->port)) if (SCM_OPOUTPORTP (scm_i_port_table[i]->port))
scm_flush (scm_i_port_table[i]->port); scm_flush (scm_i_port_table[i]->port);
} }
scm_mutex_unlock (&scm_i_port_table_mutex);
return SCM_UNSPECIFIED; return SCM_UNSPECIFIED;
} }
#undef FUNC_NAME #undef FUNC_NAME
@ -1520,7 +1527,7 @@ write_void_port (SCM port SCM_UNUSED,
SCM SCM
scm_void_port (char *mode_str) scm_void_port (char *mode_str)
{ {
SCM_DEFER_INTS; scm_mutex_lock (&scm_i_port_table_mutex);
{ {
int mode_bits = scm_mode_bits (mode_str); int mode_bits = scm_mode_bits (mode_str);
SCM answer = scm_new_port_table_entry (scm_tc16_void_port); SCM answer = scm_new_port_table_entry (scm_tc16_void_port);
@ -1530,7 +1537,7 @@ scm_void_port (char *mode_str)
SCM_SETSTREAM (answer, 0); SCM_SETSTREAM (answer, 0);
SCM_SET_CELL_TYPE (answer, scm_tc16_void_port | mode_bits); SCM_SET_CELL_TYPE (answer, scm_tc16_void_port | mode_bits);
SCM_ALLOW_INTS; scm_mutex_unlock (&scm_i_port_table_mutex);
return answer; return answer;
} }
} }

View file

@ -3,7 +3,7 @@
#ifndef SCM_PORTS_H #ifndef SCM_PORTS_H
#define SCM_PORTS_H #define SCM_PORTS_H
/* Copyright (C) 1995,1996,1997,1998,1999,2000,2001 Free Software Foundation, Inc. /* Copyright (C) 1995,1996,1997,1998,1999,2000,2001, 2003 Free Software Foundation, Inc.
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public
@ -26,6 +26,7 @@
#include "libguile/print.h" #include "libguile/print.h"
#include "libguile/struct.h" #include "libguile/struct.h"
#include "libguile/threads.h"
/* Not sure if this is a good idea. We need it for off_t. */ /* Not sure if this is a good idea. We need it for off_t. */
#include <sys/types.h> #include <sys/types.h>
@ -110,6 +111,7 @@ typedef struct
SCM_API scm_t_port **scm_i_port_table; SCM_API scm_t_port **scm_i_port_table;
SCM_API long scm_i_port_table_size; /* Number of ports in scm_i_port_table. */ SCM_API long scm_i_port_table_size; /* Number of ports in scm_i_port_table. */
SCM_API scm_t_mutex scm_i_port_table_mutex;
#define SCM_READ_BUFFER_EMPTY_P(c_port) (c_port->read_pos >= c_port->read_end) #define SCM_READ_BUFFER_EMPTY_P(c_port) (c_port->read_pos >= c_port->read_end)

View file

@ -1,4 +1,4 @@
/* Copyright (C) 1995,1996,1998,1999,2000,2001,2002 Free Software Foundation, Inc. /* Copyright (C) 1995,1996,1998,1999,2000,2001,2002, 2003 Free Software Foundation, Inc.
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public
@ -260,7 +260,7 @@ scm_mkstrport (SCM pos, SCM str, long modes, const char *caller)
if (!((modes & SCM_WRTNG) || (modes & SCM_RDNG))) if (!((modes & SCM_WRTNG) || (modes & SCM_RDNG)))
scm_misc_error ("scm_mkstrport", "port must read or write", SCM_EOL); scm_misc_error ("scm_mkstrport", "port must read or write", SCM_EOL);
SCM_DEFER_INTS; scm_mutex_lock (&scm_i_port_table_mutex);
z = scm_new_port_table_entry (scm_tc16_strport); z = scm_new_port_table_entry (scm_tc16_strport);
pt = SCM_PTAB_ENTRY(z); pt = SCM_PTAB_ENTRY(z);
SCM_SETSTREAM (z, SCM_UNPACK (str)); SCM_SETSTREAM (z, SCM_UNPACK (str));
@ -272,7 +272,7 @@ scm_mkstrport (SCM pos, SCM str, long modes, const char *caller)
pt->rw_random = 1; pt->rw_random = 1;
SCM_ALLOW_INTS; scm_mutex_unlock (&scm_i_port_table_mutex);
/* ensure write_pos is writable. */ /* ensure write_pos is writable. */
if ((modes & SCM_WRTNG) && pt->write_pos == pt->write_end) if ((modes & SCM_WRTNG) && pt->write_pos == pt->write_end)

View file

@ -1,4 +1,4 @@
/* Copyright (C) 1995,1996,1998,1999,2000,2001, 2002 Free Software Foundation, Inc. /* Copyright (C) 1995,1996,1998,1999,2000,2001, 2002, 2003 Free Software Foundation, Inc.
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public
@ -192,14 +192,14 @@ SCM_DEFINE (scm_make_soft_port, "make-soft-port", 2, 0, 0,
SCM_ASSERT ((vlen == 5) || (vlen == 6), pv, 1, FUNC_NAME); SCM_ASSERT ((vlen == 5) || (vlen == 6), pv, 1, FUNC_NAME);
SCM_VALIDATE_STRING (2, modes); SCM_VALIDATE_STRING (2, modes);
SCM_DEFER_INTS; scm_mutex_lock (&scm_i_port_table_mutex);
z = scm_new_port_table_entry (scm_tc16_sfport); z = scm_new_port_table_entry (scm_tc16_sfport);
pt = SCM_PTAB_ENTRY (z); pt = SCM_PTAB_ENTRY (z);
scm_port_non_buffer (pt); scm_port_non_buffer (pt);
SCM_SET_CELL_TYPE (z, scm_tc16_sfport | scm_mode_bits (SCM_STRING_CHARS (modes))); SCM_SET_CELL_TYPE (z, scm_tc16_sfport | scm_mode_bits (SCM_STRING_CHARS (modes)));
SCM_SETSTREAM (z, SCM_UNPACK (pv)); SCM_SETSTREAM (z, SCM_UNPACK (pv));
SCM_ALLOW_INTS; scm_mutex_unlock (&scm_i_port_table_mutex);
return z; return z;
} }
#undef FUNC_NAME #undef FUNC_NAME