diff options
author | Ian Lance Taylor <iant@golang.org> | 2021-03-17 12:19:01 -0700 |
---|---|---|
committer | Ian Lance Taylor <iant@golang.org> | 2021-03-17 12:19:01 -0700 |
commit | f10c7c4596dda99d2ee872c995ae4aeda65adbdf (patch) | |
tree | a3451277603bc8fbe2eddce5f4ad63f790129a01 /libgfortran/io | |
parent | bc636c218f2b28da06cd1404d5b35d1f8cc43fd1 (diff) | |
parent | f3e9c98a9f40fc24bb4ecef6aaa94ff799c8d587 (diff) | |
download | gcc-f10c7c4596dda99d2ee872c995ae4aeda65adbdf.zip gcc-f10c7c4596dda99d2ee872c995ae4aeda65adbdf.tar.gz gcc-f10c7c4596dda99d2ee872c995ae4aeda65adbdf.tar.bz2 |
Merge from trunk revision f3e9c98a9f40fc24bb4ecef6aaa94ff799c8d587.
Diffstat (limited to 'libgfortran/io')
-rw-r--r-- | libgfortran/io/transfer.c | 32 | ||||
-rw-r--r-- | libgfortran/io/unit.c | 1 |
2 files changed, 24 insertions, 9 deletions
diff --git a/libgfortran/io/transfer.c b/libgfortran/io/transfer.c index 27bee9d..71a9356 100644 --- a/libgfortran/io/transfer.c +++ b/libgfortran/io/transfer.c @@ -4339,6 +4339,7 @@ export_proto(st_read_done); void st_read_done_worker (st_parameter_dt *dtp) { + bool free_newunit = false; finalize_transfer (dtp); free_ionml (dtp); @@ -4358,7 +4359,7 @@ st_read_done_worker (st_parameter_dt *dtp) free (dtp->u.p.current_unit->ls); dtp->u.p.current_unit->ls = NULL; } - newunit_free (dtp->common.unit); + free_newunit = true; } if (dtp->u.p.unit_is_internal || dtp->u.p.format_not_saved) { @@ -4366,6 +4367,14 @@ st_read_done_worker (st_parameter_dt *dtp) free_format (dtp); } } + unlock_unit (dtp->u.p.current_unit); + if (free_newunit) + { + /* Avoid inverse lock issues by placing after unlock_unit. */ + LOCK (&unit_lock); + newunit_free (dtp->common.unit); + UNLOCK (&unit_lock); + } } void @@ -4382,11 +4391,10 @@ st_read_done (st_parameter_dt *dtp) if (dtp->u.p.async) enqueue_done (dtp->u.p.current_unit->au, AIO_READ_DONE); } + unlock_unit (dtp->u.p.current_unit); } else - st_read_done_worker (dtp); - - unlock_unit (dtp->u.p.current_unit); + st_read_done_worker (dtp); /* Calls unlock_unit. */ } library_end (); @@ -4406,6 +4414,7 @@ st_write (st_parameter_dt *dtp) void st_write_done_worker (st_parameter_dt *dtp) { + bool free_newunit = false; finalize_transfer (dtp); if (dtp->u.p.current_unit != NULL @@ -4446,7 +4455,7 @@ st_write_done_worker (st_parameter_dt *dtp) free (dtp->u.p.current_unit->ls); dtp->u.p.current_unit->ls = NULL; } - newunit_free (dtp->common.unit); + free_newunit = true; } if (dtp->u.p.unit_is_internal || dtp->u.p.format_not_saved) { @@ -4454,6 +4463,14 @@ st_write_done_worker (st_parameter_dt *dtp) free_format (dtp); } } + unlock_unit (dtp->u.p.current_unit); + if (free_newunit) + { + /* Avoid inverse lock issues by placing after unlock_unit. */ + LOCK (&unit_lock); + newunit_free (dtp->common.unit); + UNLOCK (&unit_lock); + } } extern void st_write_done (st_parameter_dt *); @@ -4476,11 +4493,10 @@ st_write_done (st_parameter_dt *dtp) if (dtp->u.p.async) enqueue_done (dtp->u.p.current_unit->au, AIO_WRITE_DONE); } + unlock_unit (dtp->u.p.current_unit); } else - st_write_done_worker (dtp); - - unlock_unit (dtp->u.p.current_unit); + st_write_done_worker (dtp); /* Calls unlock_unit. */ } library_end (); diff --git a/libgfortran/io/unit.c b/libgfortran/io/unit.c index 2ea6643..b0cc6ab 100644 --- a/libgfortran/io/unit.c +++ b/libgfortran/io/unit.c @@ -456,7 +456,6 @@ set_internal_unit (st_parameter_dt *dtp, gfc_unit *iunit, int kind) { gfc_offset start_record = 0; - iunit->unit_number = dtp->common.unit; iunit->recl = dtp->internal_unit_len; iunit->internal_unit = dtp->internal_unit; iunit->internal_unit_len = dtp->internal_unit_len; |