Fortran: Async I/O - avoid unlocked unlocking [PR100352]
authorTobias Burnus <tobias@codesourcery.com>
Sun, 2 May 2021 16:16:17 +0000 (18:16 +0200)
committerTobias Burnus <tobias@codesourcery.com>
Sun, 2 May 2021 16:16:17 +0000 (18:16 +0200)
Follow up to PR100352, which moved unit unlocking to st_*_done_worker to
avoid lock order reversal; however, as async_io uses a different lock,
the (unlocked locked) unit lock shall not be unlocked there.

libgfortran/ChangeLog:

PR libgomp/100352
* io/transfer.c (st_read_done_worker, st_write_done_worker): Add new
arg whether to unlock unit.
(st_read_done, st_write_done): Call it with true.
* io/async.c (async_io): Call it with false.
* io/io.h (st_write_done_worker, st_read_done_worker): Update prototype.

libgfortran/io/async.c
libgfortran/io/io.h
libgfortran/io/transfer.c

index d216ace1947cbd5d4df3c214e284d8f9834ba15d..247008ca801d22ad2bd6f950b810c95e281e04e7 100644 (file)
@@ -117,13 +117,13 @@ async_io (void *arg)
                {
                case AIO_WRITE_DONE:
                  NOTE ("Finalizing write");
-                 st_write_done_worker (au->pdt);
+                 st_write_done_worker (au->pdt, false);
                  UNLOCK (&au->io_lock);
                  break;
 
                case AIO_READ_DONE:
                  NOTE ("Finalizing read");
-                 st_read_done_worker (au->pdt);
+                 st_read_done_worker (au->pdt, false);
                  UNLOCK (&au->io_lock);
                  break;
 
index e0007c6bfe57227a844cd114b0c0625eb9beed8e..3355bc2fd8d0880f2359395f0d9cb7e09b9476a5 100644 (file)
@@ -1083,11 +1083,11 @@ default_precision_for_float (int kind)
 #endif
 
 extern void
-st_write_done_worker (st_parameter_dt *);
+st_write_done_worker (st_parameter_dt *, bool);
 internal_proto (st_write_done_worker);
 
 extern void
-st_read_done_worker (st_parameter_dt *);
+st_read_done_worker (st_parameter_dt *, bool);
 internal_proto (st_read_done_worker);
 
 extern void
index 71a935652e37bcc9e1bfc4a41f6f9fd3935c1838..36e35b48cd32cd107ce27dd38c86e679c972eea6 100644 (file)
@@ -4337,7 +4337,7 @@ extern void st_read_done (st_parameter_dt *);
 export_proto(st_read_done);
 
 void
-st_read_done_worker (st_parameter_dt *dtp)
+st_read_done_worker (st_parameter_dt *dtp, bool unlock)
 {
   bool free_newunit = false;
   finalize_transfer (dtp);
@@ -4367,7 +4367,8 @@ st_read_done_worker (st_parameter_dt *dtp)
          free_format (dtp);
        }
     }
-   unlock_unit (dtp->u.p.current_unit);
+   if (unlock)
+     unlock_unit (dtp->u.p.current_unit);
    if (free_newunit)
      {
        /* Avoid inverse lock issues by placing after unlock_unit.  */
@@ -4394,7 +4395,7 @@ st_read_done (st_parameter_dt *dtp)
          unlock_unit (dtp->u.p.current_unit);
        }
       else
-       st_read_done_worker (dtp);  /* Calls unlock_unit.  */
+       st_read_done_worker (dtp, true);  /* Calls unlock_unit.  */
     }
 
   library_end ();
@@ -4412,7 +4413,7 @@ st_write (st_parameter_dt *dtp)
 
 
 void
-st_write_done_worker (st_parameter_dt *dtp)
+st_write_done_worker (st_parameter_dt *dtp, bool unlock)
 {
   bool free_newunit = false;
   finalize_transfer (dtp);
@@ -4463,7 +4464,8 @@ st_write_done_worker (st_parameter_dt *dtp)
          free_format (dtp);
        }
     }
-   unlock_unit (dtp->u.p.current_unit);
+   if (unlock)
+     unlock_unit (dtp->u.p.current_unit);
    if (free_newunit)
      {
        /* Avoid inverse lock issues by placing after unlock_unit.  */
@@ -4496,7 +4498,7 @@ st_write_done (st_parameter_dt *dtp)
          unlock_unit (dtp->u.p.current_unit);
        }
       else
-       st_write_done_worker (dtp);  /* Calls unlock_unit.  */
+       st_write_done_worker (dtp, true);  /* Calls unlock_unit.  */
     }
 
   library_end ();