[c++-pthreads] Re: thread-safety definition
Dave Butenhof
David.Butenhof at hp.com
Fri Jan 9 12:20:18 UTC 2004
David Abrahams wrote:
>>Ah. I see the problem. I believe that you neglected to file in
>>triplicate the official "List of all matters with which I disagree so
>>please don't shout when discussing them" form. Didn't you? ;-)
>>
>>
>I filed. It was *you* who neglected to check with the department of
>archival non-shouting topic storage, wasn't it?
>
>
Aw, shoot. I forgot to pay the bill on my automatic update service, and
it expired! Sorry 'bout that.
>>>If you make cancellations behave sufficiently like an ordinary C++
>>>exception (either of Nathan's or Jason's models would do that I think)
>>>then it's neither "IMPOSSIBLE" nor even difficult. A great deal of
>>>thread-safe exception-safe C++ library code would behave perfectly
>>>well under those conditions.
>>>
>>Well, it should be no surprise that this discussion has fragmented
>>into too many different little pathways for anyone to keep track of
>>them.
>>
>>If cancel is implemented completely as a "full stature" C++ exception,
>>and none of the "exception safe" code does anything silly like
>>"catch(...)" without a re-throw, then, yes, it's likely to be
>>reasonably cancel-safe.
>>
>>
>Even if only *some* of it does that, Nathan and Jason's models are
>both likely to result in an eventual cancellation.
>
>
I need to start keeping a scorecard. Lessee here, Nathan's model I
believe could be trivially characterized as "return failure status on
any cancellation point until you hit a C++ function allowed to throw".
This would apparently disable any cleanup operations involving
cancellation points (they'd fail) at least prior to the first throw
point -- and it's not precisely clear how the "pending cancel" state is
to be managed even beyond that point. While it might eventually lead to
cancellation, it won't reliably perform cleanup. This seems to me to be
more complicated, less predictable, less compatible, and less reliable
than simply using exceptions integrated with the existing POSIX cleanup
mechanism.
Jason's model, putting together the puzzle pieces from various messages
here, appears to be basing cancel on an ordinary ("finalizable") C++
exception, which would be raised by any and all cancellation points; but
if the exception object were to be destroyed (by finalization), the
"pending cancel" would (might?) be reasserted. I personally feel that it
ought to be reasonable to finalize the cancel and continue operation. If
that wasn't really what the application intended then it's an
application error; but there are cases where it's arguably reasonable,
and the capability falls naturally out of the model. Besides,
"reasserting cancel" in all the right places and no other places sounds
like one of those projects that ends up being a lot more subtle and
error-prone than anyone ever expects. ;-)
>>(Though some code might need to be aware that an uncaught cancel
>>will terminate the thread rather than the process!)
>>
>>
>Remember, we're talking about library code. Usually it's only used
>"on the inside" of threads so it doesn't care whether when it's
>terminated, it's the process or only a thread.
>
>>But I was really responding to the ideas about turning cancel into a
>>return status
>>
>>
>...only for 'C' functions which ordinarily have a return status and don't
>throw... did you miss that?
>
It doesn't matter. There are many problems lurking here, and only one of
the more obvious is that this attempt to avoid breaking C code that
depends on 'if (error) {cleanup(); return error;}' will still break if
'cleanup()' depends on any cancellation points... which in fact is quite
likely if 'error' originates from a cancellation point (e.g., I/O). I
also don't believe that a sufficient body of library code really follows
the simple and direct 'if (error) return error;' pattern to make this
strategy particularly useful even without the cleanup issues -- but
that's a different matter. (It might actually be better if the pending
cancel wasn't "sticky", since then the cleanup at least might succeed;
but then you'll lose cancels all over the place, and that's definitely
not acceptable. It's fine for a thread to CHOOSE not to accept a cancel,
either by keeping cancellation disabled or by not calling a cancellation
point; but it's not OK to lose a delivered cancel. You can declare this
to be the application/library developer's job rather than the
implementation's job -- but that just means all this "broken" C code
that fails to propagate errors needs to be redesigned; and you haven't
solved any real problem. That's the basic point: it needs to be analyzed
and likely redesigned to be cancel-safe. You simply can't avoid that
requirement.)
A) You cannot transparently make non cancel-safe C code cancel-safe, no
matter how you try.
B) Delivering cancellation as a C++ exception will make much (though not
all) exception-safe C++ "translucently" cancel-safe.
C) POSIX C cancel-safe code is already cancel-safe, but for an
application containing mixed call stacks to remain cancel-safe, POSIX
cleanup and C++ exceptions must be integrated into a single unwind;
i.e., (by whatever name) basing both on a common exception library.
D) There are no useful or interestingly large bodies of rigorously
"cancel-safe" C code that are not POSIX cancel-safe.
In other words, cancel-as-exception, and pthread_cleanup_push as a
C-based "try" extension, gives you all the cancel-safety you can
reasonably expect without recoding (and likely redesign). That's all
that's needed. No less will suffice, and any more is needless
complication. Non cancel-safe code will continue to work just fine as
long as it's NOT cancelled -- which ought to be no terrible restriction
since it was clearly written in and for an environment where
cancellation either did not exist or wasn't needed.
--
/--------------------[ David.Butenhof at hp.com ]--------------------\
| Hewlett-Packard Company Tru64 UNIX & VMS Thread Architect |
| My book: http://www.awl.com/cseng/titles/0-201-63392-2/ |
\----[ http://homepage.mac.com/dbutenhof/Threads/Threads.html ]---/
More information about the c++-pthreads
mailing list