https://gcc.gnu.org/bugzilla/show_bug.cgi?id=119136

--- Comment #15 from Thomas Koenig <tkoenig at gcc dot gnu.org> ---
(In reply to Jerry DeLisle from comment #14)
> Created attachment 63178 [details]
> Preliminary patch that partially fixes this
> 
> The attached patch detects external file recurise I/O. As noted in the
> comment, internal units needs to be handled differently. I am still sorting
> it out. As is, this regression tests OK.

A few nits/questions:

I do not think gfc_unit is externally visible, so it might make
sense to put is_active together with has_size, to save a few bytes.

The pre-existing comment for get_gfc_unit_from_unit_root is wrong: It says

/* get_gfc_unit_from_root()-- Given an integer, return a pointer
   to the unit structure. Returns NULL if the unit does not exist,
   otherwise returns a locked unit. */

but no locking is done.  This could be adjusted in the patch.

Regarding the logic:  I think we have the potential for race conditions
here.  I would suggest something like (completely untested)

void
check_for_recursive (st_parameter_dt *dtp)
{
  gfc_unit *p;

  p = get_gfc_unit_from_unit_root(dtp->common.unit);
  if (p != NULL)
    {
      if (!(dtp->common.flags & IOPARM_DT_HAS_INTERNAL_UNIT))
        {
          /* The unit is external.  */

          /* If the unit is locked by somebody else, something is certainly
             wrong.  */

          if (TRYLOCK(&p->lock)) {
            generate_error (&dtp->common, LIBERROR_RECURSIVE_IO, NULL);
            return;
          }
          if (p->is_active && (p->child_dtio == 0))
            generate_error (&dtp->common, LIBERROR_RECURSIVE_IO, NULL);
          else
            p->is_active = true;

          UNLOCK(&p->lock);

        }
      else
        {
          /* Checking an internal unit will have to be different.  */
        }
    }
}

Reply via email to