Ignore:
Timestamp:
Oct 6, 2021, 8:37:21 PM (20 months ago)
Author:
Peter A. Buhr <pabuhr@…>
Branches:
ADT, enum, forall-pointer-decay, master, pthread-emulation, qualifiedEnum
Children:
237df76
Parents:
e16eb460
Message:

remove mutual-exclusion acquire for streams, add EINTR restarts for C stream functions

File:
1 edited

Legend:

Unmodified
Added
Removed
  • libcfa/src/fstream.cfa

    re16eb460 r8dcb832  
    1010// Created On       : Wed May 27 17:56:53 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Oct  1 08:10:21 2021
    13 // Update Count     : 473
     12// Last Modified On : Wed Oct  6 18:39:13 2021
     13// Update Count     : 508
    1414//
    1515
     
    3636        prt$ = false;
    3737        sawNL$ = false;
    38         acquired$ = false;
    3938        sepSetCur$( os, sepGet( os ) );
    4039        sepSet( os, " " );
     
    101100        if ( &os == &exit ) exit( EXIT_FAILURE );
    102101        if ( &os == &abort ) abort();
    103         if ( os.acquired$ ) { os.acquired$ = false; unlock( os ); }
    104102} // ends
    105103
     
    109107
    110108void open( ofstream & os, const char name[], const char mode[] ) {
    111         FILE * file = fopen( name, mode );
     109        FILE * file;
     110    for ( cnt; 10 ) {
     111                errno = 0;
     112                file = fopen( name, mode );
     113          if ( file != 0p || errno != EINTR ) break;            // timer interrupt ?
     114          if ( cnt == 9 ) abort( "ofstream open EINTR spinning exceeded" );
     115    } // for
    112116        if ( file == 0p ) {
    113117                throw (Open_Failure){ os };
     
    123127  if ( (FILE *)(file$) == (FILE *)stdout || (FILE *)(file$) == (FILE *)stderr ) return;
    124128
    125         if ( fclose( (FILE *)(file$) ) == EOF ) {
     129        int ret;
     130    for ( cnt; 10 ) {
     131                errno = 0;
     132                ret = fclose( (FILE *)(file$) );
     133          if ( ret != EOF || errno != EINTR ) break;            // timer interrupt ?
     134          if ( cnt == 9 ) abort( "ofstream open EINTR spinning exceeded" );
     135    } // for
     136        if ( ret == EOF ) {
    126137                throw (Close_Failure){ os };
    127138                // abort | IO_MSG "close output" | nl | strerror( errno );
     
    146157        va_list args;
    147158        va_start( args, format );
    148         int len = vfprintf( (FILE *)(os.file$), format, args );
     159               
     160        int len;
     161    for ( cnt; 10 ) {
     162                errno = 0;
     163                len = vfprintf( (FILE *)(os.file$), format, args );
     164          if ( len != EOF || errno != EINTR ) break;            // timer interrupt ?
     165          if ( cnt == 9 ) abort( "ofstream fmt EINTR spinning exceeded" );
     166    } // for
    149167        if ( len == EOF ) {
    150168                if ( ferror( (FILE *)(os.file$) ) ) {
     
    158176        return len;
    159177} // fmt
    160 
    161 void acquire( ofstream & os ) with( os ) {
    162         lock( os );                                                                                     // may increase recursive lock
    163         if ( ! acquired$ ) acquired$ = true;                            // not locked ?
    164         else unlock( os );                                                                      // unwind recursive lock at start
    165 } // acquire
    166 
    167 void ?{}( osacquire & acq, ofstream & os ) { &acq.os = &os; lock( os ); }
    168 void ^?{}( osacquire & acq ) { unlock( acq.os ); }
    169178
    170179static ofstream soutFile = { (FILE *)stdout };
     
    195204        file$ = file;
    196205        nlOnOff$ = false;
    197         acquired$ = false;
    198206} // ?{}
    199207
     
    215223
    216224void ends( ifstream & is ) {
    217         if ( is.acquired$ ) { is.acquired$ = false; unlock( is ); }
    218225} // ends
    219226
     
    221228
    222229void open( ifstream & is, const char name[], const char mode[] ) {
    223         FILE * file = fopen( name, mode );
     230        FILE * file;
     231    for ( cnt; 10 ) {
     232                errno = 0;
     233                file = fopen( name, mode );
     234          if ( file != 0p || errno != EINTR ) break;            // timer interrupt ?
     235          if ( cnt == 9 ) abort( "ifstream open EINTR spinning exceeded" );
     236    } // for
    224237        if ( file == 0p ) {
    225238                throw (Open_Failure){ is };
     
    235248  if ( (FILE *)(file$) == (FILE *)stdin ) return;
    236249
    237         if ( fclose( (FILE *)(file$) ) == EOF ) {
     250        int ret;
     251    for ( cnt; 10 ) {
     252                errno = 0;
     253                ret = fclose( (FILE *)(file$) );
     254          if ( ret != EOF || errno != EINTR ) break;            // timer interrupt ?
     255          if ( cnt == 9 ) abort( "ifstream close EINTR spinning exceeded" );
     256    } // for
     257        if ( ret == EOF ) {
    238258                throw (Close_Failure){ is };
    239259                // abort | IO_MSG "close input" | nl | strerror( errno );
    240260        } // if
    241         file$ = 0p;
     261        file$ = 0p;                                                                                     // safety after close
    242262} // close
    243263
     
    268288int fmt( ifstream & is, const char format[], ... ) {
    269289        va_list args;
    270 
    271290        va_start( args, format );
    272         int len = vfscanf( (FILE *)(is.file$), format, args );
     291
     292        int len;
     293    for () {                                                                                    // no check for EINTR limit waiting for keyboard input
     294                errno = 0;
     295                len = vfscanf( (FILE *)(is.file$), format, args );
     296          if ( len != EOF || errno != EINTR ) break;            // timer interrupt ?
     297    } // for
    273298        if ( len == EOF ) {
    274299                if ( ferror( (FILE *)(is.file$) ) ) {
     
    279304        return len;
    280305} // fmt
    281 
    282 void acquire( ifstream & is ) with( is ) {
    283         lock( is );                                                                                     // may increase recursive lock
    284         if ( ! acquired$ ) acquired$ = true;                            // not locked ?
    285         else unlock( is );                                                                      // unwind recursive lock at start
    286 } // acquire
    287 
    288 void ?{}( isacquire & acq, ifstream & is ) { &acq.is = &is; lock( is ); }
    289 void ^?{}( isacquire & acq ) { unlock( acq.is ); }
    290306
    291307static ifstream sinFile = { (FILE *)stdin };
Note: See TracChangeset for help on using the changeset viewer.