Re: [c++-pthreads] cancellation points report failure
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [c++-pthreads] cancellation points report failure



I apologize for the delay in replying to this.  It took a while
to see what you are getting at.

On Mon, Dec 22, 2003 at 08:13:20AM +0100, Alexander Terekhov wrote:
> 
> int peekc(FILE * f) { 
>   return ungetc(getc_unlocked(f), f); /* "The ungetc()     */
>   /* function is infrequently called relative to the other */
>   /* functions/macros so no unlocked variation is needed." */
>   /*                                                       */
>   /* How fascinating. Well, __fsetlocking() is my friend.  */
> }
>
> Both getc_unlocked() and ungetc() are cancelation points. This 
> function offers basic exception safety and basic thread safety 
> (and it is thread-cancel-safe, of course). Do you really want 
> me to change it to something like
> 
> int peekc(FILE * f) { 
>   int c = ungetc(getc_unlocked(f), f); 
>   if (c == EOF && !feof(f) && errno == ECANCELED) {
>     /*... ?re-inject cancel request? ... */
>     /*... ?re-enable cancel state? ... */
>     pthread_testcancel(); /* hurrah! */
>   }
>   return c;
> }

I don't understand where you get that.  I thought I had made clear
that I didn't expect any ordinary (correct!) C library code to need
changes.  Since getc_unlocked(f) may always return EOF, so you had 
better be prepared for it.  I.e. your original function is of 
questionable correctness.  However, it would correctly return
EOF in the event of a cancellation (under my proposed model), 
so that's OK.  (The read position would be left indeterminate,
but that's how you wrote it.)
 
> What if someone[1] has it written as
> 
> int peekc(FILE * f) { 
>   int c = getc(f); 
>   if (c != EOF) 
>     ungetc(c, f);
>   return c;
> }
> 
> and cancelation hits at "unchecked" ungetc(), in your model?
> 
> [1] google.com/groups?selm=slrn8cvkde.mf3.kaz@xxxxxxxxxxxxxxxxxxx
 
Buggy code is buggy.  That code looks better than your original
version, though.  This

 int peekc(FILE * f) { 
   int c = getc(f); 
   return (c == EOF) ? EOF : ungetc(c, f);
 }

would be more strictly correct.  However, the version in [1] would 
not introduce any corruption.  Any subsequent attempt to read the 
(not-really) put-back character would (also) fail, and control would, 
eventually, bubble out to a top-level context.

Nathan Myers
ncm@xxxxxxxxxxx