I intent to commit this patch - created mostly by Janne - soon to gcc-4_6-branch; it should solve a build issue.

The patch was build and regtested on x86-64-linux and build and tested on MinGW and Cygwin by Kai.

It is a follow up to http://gcc.gnu.org/ml/fortran/2011-10/msg00132.html / http://gcc.gnu.org/ml/gcc-cvs/2011-10/msg00734.html

Please speak up immediately, if you have objects against the committal. (Another option would be to revert previous patch, which solved a severe performance regression on Windows - thus that patch plus this patch is better.)

Sorry for disrupting the 4.6.2 process a bit.

Tobias
libgfortran/
2011-10-19  Janne Blomqvist  <j...@gcc.gnu.org>
	    Kai Tietz  <kti...@redhat.com>
	    Tobias Burnus  <bur...@net-b.de>

	PR fortran/50016
	* io/unix.h (flush_sync): Add new libgfortran-internal prototype.
	* io/unix.c (flush_sync): New function, which calls sflush and
	on MinGW(-w64) also _commit.
	(flush_all_units, flush_all_units_1): Replace sflush/_commit by
	flush_sync.
	* io/file_pos.c (st_flush): Replace sflush/_commit by flush_sync.
	* io/intrinsics.c (flush_i4, flush_i8): Ditto.

Index: libgfortran/io/file_pos.c
===================================================================
--- libgfortran/io/file_pos.c	(revision 180180)
+++ libgfortran/io/file_pos.c	(working copy)
@@ -451,11 +451,7 @@ st_flush (st_parameter_filepos *fpp)
       if (u->flags.form == FORM_FORMATTED)
         fbuf_flush (u, u->mode);
 
-      sflush (u->s);
-#ifdef _WIN32
-      /* Without _commit, changes are not visible to other file descriptors.  */
-      _commit (u->s->fd);
-#endif
+      flush_sync (u->s);
       unlock_unit (u);
     }
   else
Index: libgfortran/io/unix.c
===================================================================
--- libgfortran/io/unix.c	(revision 180180)
+++ libgfortran/io/unix.c	(working copy)
@@ -1522,6 +1522,23 @@ retry:
   return u;
 }
 
+
+/* Flush dirty data, making sure that OS metadata is updated as
+   well. Note that this is VERY slow on mingw due to committing data
+   to stable storage.  */
+int
+flush_sync (stream * s)
+{
+  if (sflush (s) == -1)
+    return -1;
+#ifdef __MINGW32__
+  if (_commit (((unix_stream *)s)->fd) == -1)
+    return -1;
+#endif
+  return 0;
+}
+
+
 static gfc_unit *
 flush_all_units_1 (gfc_unit *u, int min_unit)
 {
@@ -1538,14 +1555,7 @@ flush_all_units_1 (gfc_unit *u, int min_unit)
 	  if (__gthread_mutex_trylock (&u->lock))
 	    return u;
 	  if (u->s)
-	    {
-	      sflush (u->s);
-#ifdef _WIN32
-	      /* Without _commit, changes are not visible to other
-		 file descriptors.  */
-	      _commit (u->s->fd);
-#endif
-	    }
+	    flush_sync (u->s);
 	  __gthread_mutex_unlock (&u->lock);
 	}
       u = u->right;
@@ -1575,12 +1585,7 @@ flush_all_units (void)
 
       if (u->closed == 0)
 	{
-	  sflush (u->s);
-#ifdef _WIN32
-	  /* Without _commit, changes are not visible to other
-	     file descriptors.  */
-	  _commit (u->s->fd);
-#endif
+	  flush_sync (u->s);
 	  __gthread_mutex_lock (&unit_lock);
 	  __gthread_mutex_unlock (&u->lock);
 	  (void) predec_waiting_locked (u);
Index: libgfortran/io/intrinsics.c
===================================================================
--- libgfortran/io/intrinsics.c	(revision 180180)
+++ libgfortran/io/intrinsics.c	(working copy)
@@ -206,12 +206,7 @@ flush_i4 (GFC_INTEGER_4 *unit)
       us = find_unit (*unit);
       if (us != NULL)
 	{
-	  sflush (us->s);
-#ifdef _WIN32
-	  /* Without _commit, changes are not visible
-	     to other file descriptors.  */
-	  _commit (u->s->fd);
-#endif
+	  flush_sync (us->s);
 	  unlock_unit (us);
 	}
     }
@@ -234,12 +229,7 @@ flush_i8 (GFC_INTEGER_8 *unit)
       us = find_unit (*unit);
       if (us != NULL)
 	{
-	  sflush (us->s);
-#ifdef _WIN32
-	  /* Without _commit, changes are not visible
-	     to other file descriptors.  */
-	  _commit (u->s->fd);
-#endif
+	  flush_sync (us->s);
 	  unlock_unit (us);
 	}
     }
Index: libgfortran/io/unix.h
===================================================================
--- libgfortran/io/unix.h	(revision 180180)
+++ libgfortran/io/unix.h	(working copy)
@@ -167,6 +167,9 @@ internal_proto(is_special);
 extern void flush_if_preconnected (stream *);
 internal_proto(flush_if_preconnected);
 
+extern int flush_sync (stream *);
+internal_proto(flush_sync);
+
 extern int stream_isatty (stream *);
 internal_proto(stream_isatty);
 

Reply via email to