IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Changeset 39997 for trunk


Ignore:
Timestamp:
Mar 5, 2017, 12:18:00 PM (9 years ago)
Author:
eugene
Message:

retry fread on I/O failure

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Ohana/src/libfits/table/F_read_T.c

    r39996 r39997  
    11# include <ohana.h>
    22# include <gfitsio.h>
     3
     4# define GFITS_FREAD_COMPLETE_READ 0
     5# define GFITS_FREAD_INCOMPLETE_FILE 1
     6# define GFITS_FREAD_INCOMPLETE_READ 2
    37
    48/*********************** fits read table ***********************************/
     
    4953}
    5054
     55// retry several times to read the file, if we hit the EOF, give up, otherwise try again
     56// sleep for 500,000 nanoseconds between attempts (or longer?)
     57off_t gfits_fread_retry (int *status, char *buffer, off_t Nbytes, FILE *f, int Nretry) {
     58 
     59  off_t Nread = 0;
     60
     61  for (int i = 0; (i < Nretry) && (Nread < Nbytes); i++) {
     62    off_t Nbyte_left = Nbytes - Nread;
     63    off_t Nread_pass = fread (&buffer[Nread], sizeof (char), Nbyte_left, f);
     64   
     65    Nread += Nread_pass;
     66    if (Nread != Nbytes) {
     67      if (feof(f)) {
     68        *status = GFITS_FREAD_INCOMPLETE_FILE;
     69        return Nread;
     70      }
     71      sleep (2);
     72      if (i < Nretry - 1) fprintf (stderr, "incomplete file read, retrying\n");
     73    }
     74  }
     75
     76  if (Nread != Nbytes) {
     77    if (feof(f)) {
     78      *status = GFITS_FREAD_INCOMPLETE_FILE;
     79    } else {
     80      *status = GFITS_FREAD_INCOMPLETE_READ;
     81    }
     82  } else {
     83    *status = GFITS_FREAD_COMPLETE_READ;
     84  }
     85  return Nread;
     86}
     87
    5188/*********************** fits read ftable data ***********************************/
    5289int gfits_fread_ftable_data (FILE *f, FTable *table, int padIfShort) {
    5390
     91  int status;
    5492  off_t Nbytes, Nread;
    5593
     
    5896  ALLOCATE (table[0].buffer, char, Nbytes);
    5997
    60   Nread = fread (table[0].buffer, sizeof (char), Nbytes, f);
    61   if (Nread != Nbytes) {
    62     if (feof(f)) {
    63       if (!gfits_fread_incomplete_case(f, table, padIfShort, Nread, Nbytes)) return FALSE;
    64     } else {
    65       off_t Nextra = Nbytes - Nread;
    66       off_t Nxread = fread (&table[0].buffer[Nread], sizeof (char), Nextra, f);
    67       Nread += Nxread;
    68       if (Nread != Nbytes) {
    69         if (!gfits_fread_incomplete_case(f, table, padIfShort, Nread, Nbytes)) return FALSE;
    70       }
    71     }
     98  Nread = gfits_fread_retry (&status, table[0].buffer, Nbytes, f, 5);
     99  if (status != GFITS_FREAD_COMPLETE_READ) {
     100    if (!gfits_fread_incomplete_case(f, table, padIfShort, Nread, Nbytes)) return FALSE;
    72101  }
    73102  table[0].validsize = Nread;
     
    108137  }
    109138
    110   Nread = fread (table[0].buffer, sizeof (char), Nbytes, f);
    111   if (Nread != Nbytes) {
    112     if (ferror (f)) {
    113       perror ("fits read error");
    114       free (table[0].buffer);
    115       return (FALSE);
    116     }
    117     fprintf (stderr, "error: fits read error in %s, read "OFF_T_FMT", need "OFF_T_FMT"\n", __func__,  Nread,  Nbytes);
    118     if (!padIfShort) {
    119       free (table[0].buffer);
    120       return (FALSE);
    121     }
    122     memset (&table[0].buffer[Nread], 0, Nbytes - Nread);
    123     fprintf (stderr, "warning: file missing data, padding with zeros: USE AT YOUR OWN RISK!\n");
     139  int status;
     140  Nread = gfits_fread_retry (&status, table[0].buffer, Nbytes, f, 5);
     141  if (status != GFITS_FREAD_COMPLETE_READ) {
     142    if (!gfits_fread_incomplete_case(f, table, padIfShort, Nread, Nbytes)) return FALSE;
    124143  }
    125144
     
    157176  Nread = fread (buffer, sizeof (char), Nbytes, f);
    158177  if (Nread != Nbytes) {
    159     perror ("fits read error");
    160     free (buffer);
    161     return (FALSE);
     178    if (feof(f)) {
     179      perror ("fits read error");
     180      free (buffer);
     181      return (FALSE);
     182    } else {
     183      // try a second time
     184      off_t Nextra = Nbytes - Nread;
     185      off_t Nxread = fread (&buffer[Nread], sizeof (char), Nextra, f);
     186      Nread += Nxread;
     187      if (Nread != Nbytes) {
     188        perror ("fits read error");
     189        free (buffer);
     190        return (FALSE);
     191      }
     192    }
    162193  }
    163194
     
    220251      Nread = fread (table[0].buffer[i], sizeof (char), Nx, f);
    221252      if (Nread != Nx) {
    222         perror ("fits read error");
    223         return (FALSE);
     253        if (feof(f)) {
     254          perror ("fits read error");
     255          return (FALSE);
     256        } else {
     257          // try a second time
     258          off_t Nextra = Nx - Nread;
     259          off_t Nxread = fread (&table[0].buffer[i][Nread], sizeof (char), Nextra, f);
     260          Nread += Nxread;
     261          if (Nread != Nx) {
     262            perror ("fits read error");
     263            return (FALSE);
     264          }
     265        }
    224266      }
    225267    }
Note: See TracChangeset for help on using the changeset viewer.