Fortran: Async I/O - avoid unlocked unlocking [PR100352]

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.
This commit is contained in:
Tobias Burnus 2021-05-02 18:16:17 +02:00
parent 7911a90527
commit a13a50047e
3 changed files with 12 additions and 10 deletions

View 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;

View 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

View 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 ();