This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Fix libgfortran ftell/fgetc/fputs/ttynam
- From: Jakub Jelinek <jakub at redhat dot com>
- To: gcc-patches at gcc dot gnu dot org, fortran at gcc dot gnu dot org
- Date: Sat, 26 Nov 2005 16:20:15 -0500
- Subject: [PATCH] Fix libgfortran ftell/fgetc/fputs/ttynam
- References: <20051126191249.9BDA81DC06D@bromo.msbb.uc.edu>
- Reply-to: Jakub Jelinek <jakub at redhat dot com>
Hi!
On Sat, Nov 26, 2005 at 02:12:49PM -0500, Jack Howarth wrote:
> (gdb) bt
> #0 0x9002b8a8 in semaphore_wait_signal_trap ()
> #1 0x900019cc in pthread_mutex_lock ()
> #2 0x0024297c in find_unit_1 (n=10, do_create=1) at ../../../gcc-4.1-20051125/libgfortran/../gcc/gthr-posix.h:521
> #3 0x002417d8 in data_transfer_init (dtp=0xbffff2cc, read_flag=3843) at ../../../gcc-4.1-20051125/libgfortran/io/transfer.c:1203
> #4 0x00002b7c in MAIN__ () at ftell_1.f90:7
> #5 0x00002c24 in main (argc=14, argv=0xf03) at ../../../gcc-4.1-20051125/libgfortran/fmain.c:18
> (gdb)
Oops, sorry. While I ran LD_PRELOAD=libpthread.so.0 make check-gfortran
back in mid October when I wrote the initial version of the patch, I forgot
to run it again now and apparently there were 5 find_unit calls added
in the mean time. Since my patch all find_unit calls if it returned
non-NULL need a matching unlock_unit call after the caller is done with the
unit, the following patch adds that. Tested with
LD_PRELOAD=libpthread.so.0 make check-gfortran on x86_64-linux
(where I managed to reproduce the fgetc_1.f90 etc. failures without
this patch).
Ok for HEAD/4.1?
2005-11-26 Jakub Jelinek <jakub@redhat.com>
* intrinsics/ftell.c (ftell, FTELL_SUB): Add unlock_unit call.
* intrinsics/fget.c (fgetc, fputs): Likewise.
* intrinsics/tty.c (ttynam): Likewise.
--- libgfortran/intrinsics/ftell.c.jj 2005-11-16 10:03:16.000000000 +0100
+++ libgfortran/intrinsics/ftell.c 2005-11-26 20:48:25.000000000 +0100
@@ -42,10 +42,12 @@ size_t
PREFIX(ftell) (int * unit)
{
gfc_unit * u = find_unit (*unit);
+ size_t ret;
if (u == NULL)
return ((size_t) -1);
- else
- return ((size_t) stream_offset (u->s));
+ ret = (size_t) stream_offset (u->s);
+ unlock_unit (u);
+ return ret;
}
#define FTELL_SUB(kind) \
@@ -58,7 +60,10 @@ PREFIX(ftell) (int * unit)
if (u == NULL) \
*offset = -1; \
else \
- *offset = stream_offset (u->s); \
+ { \
+ *offset = stream_offset (u->s); \
+ unlock_unit (u); \
+ } \
}
FTELL_SUB(1)
--- libgfortran/intrinsics/tty.c.jj 2005-11-19 09:43:34.000000000 +0100
+++ libgfortran/intrinsics/tty.c 2005-11-26 20:45:15.000000000 +0100
@@ -121,8 +121,10 @@ ttynam (char ** name, gfc_charlen_type *
{
*name_len = strlen (*name);
*name = strdup (*name);
+ unlock_unit (u);
return;
}
+ unlock_unit (u);
}
*name_len = 0;
--- libgfortran/intrinsics/fget.c.jj 2005-11-16 10:03:16.000000000 +0100
+++ libgfortran/intrinsics/fget.c 2005-11-26 20:46:32.000000000 +0100
@@ -54,6 +54,7 @@ PREFIX(fgetc) (const int * unit, char *
s = 1;
memset (c, ' ', c_len);
ret = sread (u->s, c, &s);
+ unlock_unit (u);
if (ret != 0)
return ret;
@@ -118,13 +119,16 @@ PREFIX(fputc) (const int * unit, char *
gfc_charlen_type c_len __attribute__((unused)))
{
size_t s;
+ int ret;
gfc_unit * u = find_unit (*unit);
if (u == NULL)
return -1;
s = 1;
- return swrite (u->s, c, &s);
+ ret = swrite (u->s, c, &s);
+ unlock_unit (u);
+ return ret;
}
Jakub