Hello world,

the attached patch fixes the wrong-code regression by changing the
way synchronous writes are handled on files using asynchronous I/O:
The are now handled synchronously.

This also means that two places where a wait instruction was
issued in such a case are no longer needed.

I tried to construct a failing test case for this new behavior,
but failed :-)

Regression-tested.

OK for trunk?

Regards

        Thomas
Index: io/transfer.c
===================================================================
--- io/transfer.c	(Revision 266250)
+++ io/transfer.c	(Arbeitskopie)
@@ -3189,7 +3189,7 @@ data_transfer_init (st_parameter_dt *dtp, int read
 	}
     }
 
-  if (au)
+  if (au && dtp->u.p.async)
     {
       NOTE ("enqueue_data_transfer");
       enqueue_data_transfer_init (au, dtp, read_flag);
@@ -4313,11 +4313,8 @@ st_read_done (st_parameter_dt *dtp)
 	    *dtp->id = enqueue_done_id (dtp->u.p.current_unit->au, AIO_READ_DONE);  
 	  else
 	    {
-	      enqueue_done (dtp->u.p.current_unit->au, AIO_READ_DONE);
-	      /* An asynchronous unit without ASYNCHRONOUS="YES" - make this
-		 synchronous by performing a wait operation.  */
-	      if (!dtp->u.p.async)
-		async_wait (&dtp->common, dtp->u.p.current_unit->au);
+	      if (dtp->u.p.async)
+		enqueue_done (dtp->u.p.current_unit->au, AIO_READ_DONE);
 	    }
 	}
       else
@@ -4401,7 +4398,7 @@ st_write_done (st_parameter_dt *dtp)
 {
   if (dtp->u.p.current_unit)
     {
-      if (dtp->u.p.current_unit->au)
+      if (dtp->u.p.current_unit->au && dtp->u.p.async)
 	{
 	  if (dtp->common.flags & IOPARM_DT_HAS_ID)
 	    *dtp->id = enqueue_done_id (dtp->u.p.current_unit->au,
@@ -4408,11 +4405,10 @@ st_write_done (st_parameter_dt *dtp)
 					AIO_WRITE_DONE);
 	  else
 	    {
-	      enqueue_done (dtp->u.p.current_unit->au, AIO_WRITE_DONE);
-	      /* An asynchronous unit without ASYNCHRONOUS="YES" - make this
-		 synchronous by performing a wait operation.  */
-	      if (!dtp->u.p.async)
-		async_wait (&dtp->common, dtp->u.p.current_unit->au);
+	      /* We perform synchronous I/O on an asynchronous unit, so no need
+		 to enqueue AIO_READ_DONE.  */
+	      if (dtp->u.p.async)
+		enqueue_done (dtp->u.p.current_unit->au, AIO_WRITE_DONE);
 	    }
 	}
       else
! { dg-do run }
! PR libfortran/88411
! This used to generate errors due to a mixup of
! synchronous and asynchronous execution.
! Test case by Harald Anlauf.
program gfcbug153
  implicit none
  integer :: iu, irecl
  real    :: a(100,20), b(1,3000)
  iu = 10
  a  = 0.
  b  = 0.
  inquire (iolength = irecl) a
  open (iu, file="file1.dat", access='direct', &
       asynchronous='yes', &
       recl=irecl)
  write(iu, rec=1) a(:,:)
  write(iu, rec=2) a(:,:)
  write(iu, rec=3) a(:,:)
  close (iu,status="delete")

  inquire (iolength = irecl) b
  open (iu, file="file2.dat", access='direct', &
       asynchronous='yes', &
       recl=irecl)
  write(iu, rec=1) b(:,:)
  write(iu, rec=2) b(:,:)
  write(iu, rec=3) b(:,:)
  close (iu,status="delete")
end program

Reply via email to