CVS difference for ais/ai-10266.txt

Differences between 1.11 and version 1.12
Log of other versions for file ais/ai-10266.txt

--- ais/ai-10266.txt	2004/02/12 05:58:55	1.11
+++ ais/ai-10266.txt	2004/02/21 04:15:11	1.12
@@ -78,11 +78,12 @@
 the specific handler if one has been set, otherwise the handler
 returned is null.
 
-When a task terminates, its specific handler, if not null, is
-executed. If there is no such specific handler, a default handler is
-determined by recursively searching for a non null default handler
-in the tasks upon which it depends. If such a default handler is
-determined it is executed; otherwise no handler is executed.
+As part of the finalization of a task_body, after performing the actions
+specified in 7.6 for finalization of a master, the task specific handler,
+if not null, is called. If there is no such specific handler, a default
+handler is determined by recursively searching for a non null default
+handler in the tasks upon which it depends. If such a default handler
+is determined it is executed; otherwise no handler is executed.
 
 If the task terminated due to completing the last statement
 of the task body, or as a result of waiting on a terminate
@@ -1809,6 +1810,946 @@
 1) require that the handler be called before finalizatin of local objects
 2) explicitely state (and hence warn) that local objects have been
 finalized.
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Thursday, February 12, 2004  12:20 AM
+
+Thanks. I don't think you addressed Jean-Pierre's message of December 1st.
+(It's at the end of the AI's !appendix.) If anything, the rewrite made it
+worse. Here's the text:
+
+  When a task terminates, its specific handler, if not null, is
+  executed. If there is no such specific handler, a default handler is
+  determined by recursively searching for a non null default handler
+  in the tasks upon which it depends. If such a default handler is
+  determined it is executed; otherwise no handler is executed.
+
+We had this problem in relation to task attributes (and indeed, we never
+actually finished that AI - AI-237). "When a task terminates" is not a very
+clear point in time. For task attributes, we decided it actually happens
+*after* the task terminates, but here I would expect that it happens before
+the task terminates (the task itself would call the handler in the normal
+case, at least). Jean-Pierre wanted a clear indication of where this happens
+in relation to the finalization of local objects, and that isn't covered.
+(And clearly, it is important that creators of these handlers know which.)
+Moreover, I could imagine implementing these handlers as a special
+finalization that occurs at the "right" place; in that case, it's necessary
+to know where they go on that chain (front or back).
+
+Jean-Pierre also wondered what happens if the handler creates tasks. He
+suggested erroneous (presumably so that the task's internal master can have
+already gone away). Since this is similar to finalization, it doesn't have
+to be erroneous as long as it is early enough. (Sounds like a bad idea,
+though, especially in the default handlers. There doesn't seem to be any
+problem doing task operations in a specific handler.)
+
+****************************************************************
+
+From: Robert Dewar
+Sent: Thursday, February 12, 2004  7:08 AM
+
+> In Ada 95, a task propagating an exception will be silently terminated.
+> This can be a significant hazard in high integrity systems.
+
+I must say, I find this a dubious claim. If indeed in a high integrity
+system, exceptions can be raised, then in practice this would never be
+a problem. Either you allow exception handlers, in which case you would
+insist that there be a handler in every top level task (and refuse to
+pass a system not meeting these rules), or you do not allow handlers,
+in which case you have some special mechanism for dealing with
+exceptions in any case and can handle this case.
+
+Why is it easier to provide a complex feature for dealing with this
+situation using protected records, rather than to rely on the status
+quo reflected in the above paragraph.
+
+I really don't see this as a problem AT ALL for high integrity systems.
+
+It is a problem for general purpose tasking programs in Ada, but the
+AI as proposed here offers no relief, since it is just as easy to
+insist that the top level handlers be provided as it is to insist
+that the protected procedure be put in place.
+
+Personally I would be willing to take the plunge here, and admit that
+a horrible mistake had been made, and that if an exception propagates
+out of a task, the entire program is terminated in an implementation
+dependent manner, as we do for the environment task.
+
+There are three classes of programs with respect to such a change
+
+1. Programs that never encounter the situation, they are of courtse
+unaffected by the change. This I am sure is the class into which
+almost all programs fall.
+
+2. Programs that do encounter the situation, and it is a bug. Such
+programs will welcome the change.
+
+3. Programs that count on this silent termination. I wonder if there
+are any? If there are, then this change will require them to put
+a when others => null; handler in the main task body. Such a handler
+should be considered stylistically mandatory in any case if you
+ask me.
+
+So I find this entire AI overkill
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Thursday, February 12, 2004  8:06 AM
+
+The ability to establish a default handler for
+task termination within a given task hierarchy
+is the key capability, in my view.
+
+I agree that setting termination handlers for individual tasks
+is less valuable, since it is not significantly different
+from adding a "when others" to the task body.
+However, it still has the benefit of allowing control
+over what happens in this form of failure from
+outside the offending task.  That more easily allows
+one task to manage a number of other tasks.  Without
+this, the offending task would need to know in
+what context it is running, which is more difficult for
+an instance of a task type.
+
+If you use task types, then I would imagine the programmer
+would need to create a similar capability of their
+own if we didn't provide a standard one, keying off
+the task-id, to detemine who or what should be notified
+as a result of an exception propagated to the task body.
+
+This seems like a relatively simple capability that
+should be provided as a standard package, since it
+fixes a well-recognized hole in the language.
+
+****************************************************************
+
+From: Robert A. Duff
+Sent: Thursday, February 12, 2004  8:20 AM
+
+Robert wrote:
+
+> I really don't see this as a problem AT ALL for high integrity systems.
+
+I tend to agree with Robert, here.  This AI seems to be adding a fair
+amount of complexity for rather small benefit.
+
+> Personally I would be willing to take the plunge here, and admit that
+> a horrible mistake had been made, and that if an exception propagates
+> out of a task, the entire program is terminated in an implementation
+> dependent manner, as we do for the environment task.
+
+IMHO, that's the way it should have been in the first place,
+and the incompatibility seems tolerable.
+
+However, last time I argued this point with Tucker, he was appalled at
+the idea of terminating the whole program.  I think he would prefer the
+exception to be propagated to the master.  (I wonder if the task's
+siblings get aborted in this model, or if the master waits for them to
+finish as usual.  Neither one sounds ideal to me.)
+
+There are other places where exceptions happen in embarrassing places,
+and Ada says they get lost, or turn into some catch-all like
+Program_Error.  For example, an exception propagated out of an interrupt
+handler is clearly a bug, but Ada just drops it on the floor and
+continues.  I suppose we don't want to open all these cans of worms.
+FWIW, I would design these cases differently (with 20/20 hindsight).
+
+****************************************************************
+
+From: Robert A. Duff
+Sent: Thursday, February 12, 2004  8:40 AM
+
+> This seems like a relatively simple capability that
+> should be provided as a standard package, since it
+> fixes a well-recognized hole in the language.
+
+Shrug.  All of the above is true, but I can't get too excited about it.
+
+If a task needs to know something about its context in order to handle
+errors (or do anything else, for that matter), then you can pass
+information to it as a discriminant.  (It's admittedly annoying that
+discriminants can't be of record type!  I hate horsing around with
+pointers just to pass a parameter.)
+
+You can even pass in an action to execute, if you like.
+
+If you want to fix the well-recognized hole, why not simply fix it?
+
+I'm not deadset against the feature -- I just don't see any big benefit.
+
+****************************************************************
+
+From: Robert Dewar
+Sent: Thursday, February 12, 2004  8:51 AM
+
+Robert A Duff wrote:
+
+> However, last time I argued this point with Tucker, he was appalled at
+> the idea of terminating the whole program.  I think he would prefer the
+> exception to be propagated to the master.  (I wonder if the task's
+> siblings get aborted in this model, or if the master waits for them to
+> finish as usual.  Neither one sounds ideal to me.)
+
+Tell Tuck to calm down. There are FAR less violent cases that are
+declared erroneous, and therefore could delete the system disk BEFORE
+terminating the program :-)
+
+Anyone concerned with catching this can perfectly well install a
+top level handler in their task that does whatever they like.
+
+****************************************************************
+
+From: Robert A. Duff
+Sent: Thursday, February 12, 2004  9:02 AM
+
+> Tell Tuck to calm down.
+
+Tuck is always calm.  ;-)
+
+>... There are FAR less violent cases that are
+> declared erroneous, and therefore could delete the system disk BEFORE
+> terminating the program :-)
+
+Good point.
+
+> Anyone concerned with catching this can perfectly well install a
+> top level handler in their task that does whatever they like.
+
+I think Tuck's point was that one abstraction should not be allowed to
+damage another abstraction.  E.g., task A invokes task B, and Tuck wants
+to put code in task A that protects it from bad behavior of task B.
+He doesn't want to put code in task B, because maybe it comes from
+an outside organization or is somehow untrustworthy or whatever.
+That view makes some sense, although if task B starts doing
+Unchecked_Conv of pointers, all bets are off.
+
+Maybe I should shut up and let Tuck speak for himself...
+
+****************************************************************
+
+From: Robert Dewar
+Sent: Thursday, February 12, 2004  9:21 AM
+
+Well this compositional view is somewhat less valid for tasks.
+Typically tasking is used in real time programs where you know
+what is going on with all the tasks in the system, they are not
+abstracted away anyway.
+
+Note that a Restriction:
+
+   pragma Restriction (No_Unprotected_Tasks);
+
+that insisted on top level handlers in tasks would be useful
+(I think I will file that as a GNAT enhancement request :-)
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Thursday, February 12, 2004  9:26 AM
+
+> I think Tuck's point was that one abstraction should not be allowed to
+> damage another abstraction.
+
+Yes, that is a fundamental requirement in a large system.
+
+I also believe the notion of "terminating the program" as
+a way to handle a problem makes less and less sense in the
+"modern" software world.  What exactly is a program?
+It may be a loose collection of components communicating
+and collaborating, within one machine, or across machines.
+What does it mean to terminate it?
+
+Even in Ada, we have the notion of multiple partitions.
+Many customers have Ada portions and non-Ada portions in
+the same "program."
+
+For all these reasons and more, "terminating the program"
+is an unacceptable "standardized" response to a problem in my view.
+Yes, erroneous execution can lead to any sort of disaster,
+and by definition, we don't try to specify what happens.
+
+But in any case where we do specify what happens, I don't believe
+we should ever consider "terminate the program" as an
+appropriate response, except for the clear cases of aborting
+the environment task, or library-unit elaboration failure.
+
+So that is why whenever Bob says "I think that error should just
+cause the program to terminate" I cringe. ;-)
+
+****************************************************************
+
+From: Robert A. Duff
+Sent: Thursday, February 12, 2004  11:55 AM
+
+> I also believe the notion of "terminating the program" as
+> a way to handle a problem makes less and less sense in the
+> "modern" software world.  What exactly is a program?
+
+What I *really* mean is "terminate the partition".  Ada has a notion of
+"partition", although it is necessarily implementation-dependent what it
+maps to on the underlying system.  On a "normal" Unix/Windows
+environment, I mean "terminate the current process".  On an embedded
+system, I might mean "execute a HALT instruction" or "go into an
+infinite loop" or whatever is appropriate.  On the JVM, I probably mean
+"terminate the current applet".  Note that on the JVM, there's a
+security restriction that you can't halt the virtual machine unless you
+have the appropriate privileges.
+
+Anyway, I'm at least half convinced by your arguments about handling
+exceptions at higher levels.
+
+But I still think the partition level is a more appropriate place to
+deal with this sort of fault tolerance, at least in many cases.
+I mean, one partition (a Unix process, say) dies a horrible death,
+and the other partition has to notice and do something about it.
+This way, even if the bug causes one partition to scribble all
+over the run-time system data structures and all the task's stacks, the
+other partition will be unperturbed.
+
+> It may be a loose collection of components communicating
+> and collaborating, within one machine, or across machines.
+> What does it mean to terminate it?
+>
+> Even in Ada, we have the notion of multiple partitions.
+> Many customers have Ada portions and non-Ada portions in
+> the same "program."
+
+Right -- I didn't really mean "terminate the whole program".
+I meant "partition".  (Since I usually write single-partition programs,
+I tend to use the terms interchangeably, which is wrong in this case.)
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Thursday, February 12, 2004  9:34 AM
+
+> ...
+> Well this compositional view is somewhat less valid for tasks.
+> Typically tasking is used in real time programs where you know
+> what is going on with all the tasks in the system, they are not
+> abstracted away anyway.
+
+This seems a very narrow view.  Almost all server-based systems
+(e.g. web servers, database servers, application servers)
+use multiple tasks these days, and these systems sometimes use
+abstraction quite heavily.
+
+> Note that a Restriction:
+>
+>    pragma Restriction (No_Unprotected_Tasks);
+>
+> that insisted on top level handlers in tasks would be useful
+> (I think I will file that as a GNAT enhancement request :-)
+
+That might be a nice restriction, but that still doesn't
+really address the problem of silent loss of an exception,
+nor what a task should do in its "when others" handler
+to notify its master.  I believe this is a common enough
+issue that a standardized solution is warranted, rather
+than requiring each project to invent their own task
+discriminant-based trickery for communicating up the
+task hierarchy.
+
+****************************************************************
+
+From: Robert Dewar
+Sent: Thursday, February 12, 2004  9:37 AM
+
+> So that is why whenever Bob says "I think that error should just
+> cause the program to terminate" I cringe. ;-)
+
+But all your reasons for cringing are theoretical. I can't imagine
+a real situation in which this would cause trouble.
+
+Either you intend the silent termination - please use a handler
+
+Or the program has gone disastrously wrong, and terminating it
+is as reasonable as any other response. In fact it's probably
+better, since exceptions that are not expected can cause major
+disaster themselves and can silently hang waiting for some
+other task to terminate.
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Thursday, February 12, 2004  11:14 AM
+
+My point was that Ada provides ways *within* the language to
+handle errors, even really "bad" ones.  It is not uncommon
+to have exception handlers at an outer level whose job it
+is to catch unexpected exceptions, and reset the
+state in some way, drop back to a reduced functionality, shut
+down gracefully.  Why should this particular error (an unhandled
+exception in a task body) go outside of the language, providing
+no way to handle it at a higher level?
+
+That's not the Ada way, and is bad news for long-running,
+at least semi-fault-tolerant software, like a server or
+a control system.
+
+****************************************************************
+
+From: Robert Dewar
+Sent: Thursday, February 12, 2004  11:33 AM
+
+> That's not the Ada way, and is bad news for long-running,
+> at least semi-fault-tolerant software, like a server or
+> a control system.
+
+That's theoretical, and in practice bogus (see signature, which I
+believe is attributed to Yogi Berra). Any actual implementation will
+have ways of catching unhandled exceptions from the main environment
+task (which for some reason don't seem to cause you mental distress,
+) and these same methods will of course (already are in practice,
+any decent implementation deals with this anomoly in Ada) handle
+task terminations.
+
+The important thing to realize about the bug of silent task termination
+is that this is not a problem in real problems, or critical programs.
+It is a problem during testing, and it is a problem for students,
+and crops up in odd places it's true. Once we were debugging an ACVC
+test that had an uninitailized out parameter. Ada/Ed caught this
+and raised an exception, all the tasks then started to disappear
+one by one. That's when we realized we had to have an option to
+stop that, and as I say, any decent Ada compiler already handles
+this fine, so I see no reason to have a complex addition to the
+language here.
+
+Robert Dewar
+
+"In theory there is no difference between theory and practice. In practice there is."
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Thursday, February 12, 2004  11:19 PM
+
+Robert Dewar wrote:
+
+...
+> That's theoretical, and in practice bogus (see signature, which I
+> believe is attributed to Yogi Berra). Any actual implementation will
+> have ways of catching unhandled exceptions from the main environment
+> task (which for some reason don't seem to cause you mental distress,
+> ) and these same methods will of course (already are in practice,
+> any decent implementation deals with this anomoly in Ada) handle
+> task terminations.
+
+Huh? Of course all implementations print messages or something, but that's
+hardly a useful approach for a web server or other long-running, unattended
+application. Especially as usch applications often run with no
+Standard_Output. And even if an implementation provides some sort of runtime
+notification (and I can't imagine how that would work - the environment task
+already having completed - and I'm not aware of any compilers providing it),
+you're still depending on a particular compiler's mechanism. For portable
+programs like the AdaIC web server, that's a last resort (at best).
+
+The AdaIC web server has never failed to service web requests because of a
+software problem, so far as I'm aware. (It's been clobbered by Windows, by
+long power failures, by our ISP, and by SBC, but never by an Ada
+program-related bug). That's in part because any tasks that raised
+exceptions and failed while trying to log that fact simply go away instead
+of terminating the program. (I can't say whether this actually has happened;
+by definition, such a failure would not be logged.)
+
+In any case, this requirement was originally included in the Ravenscar
+proposal by IRTAW. It was split out, and various solutions have been hashed
+about for a long time. Any benefits to regular programs are really a
+side-effect of providing facilities that the real-time communitity say they
+want. (A way to be notified of task termination.)
+
+Anyway, the primary problem I see in practice is that there is no way to
+have enough handlers in  a task (unless you give up and put in a null
+handler), simply because there always is the possibility of an exception
+being raised by the handler. This is a special problem if the exception is
+Storage_Error from running out of stack space, because any attempt to do
+anything is going to re-raise the exception.
+
+The problem I see with the proposal is that it doesn't really address this
+problem. (And I'm not sure that any proposal can.) The problem is that the
+task itself cannot execute this handler, because there may not be enough
+space to run the handler. If that's the case, you'll never get your
+notification. The real requirement, as I see it, is for out-of-band
+notification of task termination, but short of having a task somewhere
+running for that purpose, I don't see any way to implement (or describe)
+that. (And having a task simply for that purpose has too much overhead,
+especially on threaded systems.)
+
+Anyway, in the absence of something better, I endorse this proposal. But I
+really see no point in changing the "disappearing exception" behavior. It
+would break servers and other programs that are coded such that a task going
+away is non-fatal. Obviously, they could be recoded to avoid the problem,
+but forcing people to re-analyze all of their error handling for a dubious
+benefit doesn't seem to be a very smart trade-off.
+
+****************************************************************
+
+From: Alan Burns
+Sent: Thursday, February 12, 2004  11:44 PM
+
+> We had this problem in relation to task attributes (and indeed, we never
+> actually finished that AI - AI-237). "When a task terminates" is not a very
+> clear point in time. For task attributes, we decided it actually happens
+> *after* the task terminates, but here I would expect that it happens before
+> the task terminates (the task itself would call the handler in the normal
+> case, at least). Jean-Pierre wanted a clear indication of where this happens
+> in relation to the finalization of local objects, and that isn't covered.
+> (And clearly, it is important that creators of these handlers know which.)
+> Moreover, I could imagine implementing these handlers as a special
+> finalization that occurs at the "right" place; in that case, it's necessary
+> to know where they go on that chain (front or back).
+
+As you suggest, doing it early would seem sensible.
+
+So would the following be sufficient:
+
+As part of task termination, but before any local objects are
+finalised, the task specific handler ...
+
+>
+> Jean-Pierre also wondered what happens if the handler creates tasks. He
+> suggested erroneous (presumably so that the task's internal master can
+> have
+> already gone away). Since this is similar to finalization, it doesn't have
+> to be erroneous as long as it is early enough. (Sounds like a bad idea,
+> though, especially in the default handlers. There doesn't seem to be any
+> problem doing task operations in a specific handler.)
+
+I assumed we would take the same approach as finalisation routines.
+
+
+As for the more general discussion about this facility. One driver
+was for Ravenscar where the Raven implementation was asked to
+provide this type of provision. Some people wanted it just for
+debugging, others (perhaps only in theory) saw ways of programming
+degraded service and some forms of fault tolerance. Overall it
+seems like a useful (though not perfect) facility to add.
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Friday, February 13, 2004  12:28 AM
+
+> As part of task termination, but before any local objects are
+> finalised, the task specific handler ...
+
+Sounds OK to me. Do you want me to just update the AI.
+
+> I assumed we would take the same approach as finalisation routines.
+
+Which is that there is no special approach. That's fine; Ravenscar impls
+can't create tasks in a handler anyway.
+
+Wait a minute: this handler is a protected procedure. It's a bounded error
+to create a task in any protected procedure, of course, so there is no issue
+here.
+
+> As for the more general discussion about this facility. One driver
+> was for Ravenscar where the Raven implementation was asked to
+> provide this type of provision. Some people wanted it just for
+> debugging, others (perhaps only in theory) saw ways of programming
+> degraded service and some forms of fault tolerance. Overall it
+> seems like a useful (though not perfect) facility to add.
+
+Thanks for the clarification.
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Friday, February 13, 2004  5:22 AM
+
+> So would the following be sufficient:
+>
+> As part of task termination, but before any local objects are
+> finalised, the task specific handler ...
+
+That doesn't sound right either.  We want this to happen
+*after* all local objects have been finalized, but
+before the task is considered terminated, just before
+the task attributes are finalized.
+
+The implementation could use finalization to accomplish
+this, but it should be after all user-defined finalization,
+since those might themselves raise exceptions.
+
+****************************************************************
+
+From: Pascal Leroy
+Sent: Friday, February 13, 2004  7:05 AM
+
+Alan explained:
+
+> One driver was for Ravenscar where the Raven implementation was
+> asked to provide this type of provision. Some people wanted
+> it just for debugging, others (perhaps only in theory) saw
+> ways of programming degraded service and some forms of fault
+> tolerance. Overall it seems like a useful (though not
+> perfect) facility to add.
+
+This is hardly a convincing justification, Alan.  One reason is for
+debugging: I for one don't want to add junk to the language for
+debugging; there are debuggers, tracing tools, implementation-defined
+interfaces to the runtime system, etc. that provide this kind of
+facility in way which is probably more user-friendly, and doesn't
+require language support.  The other reason is "perhaps in theory"; I
+would like to be explained how this facility could be used in practice
+by a system to provide a degraded service or some kind of fault
+tolerance; I'm sorry, the usage model is not at all obvious to me.
+
+Robert proposed:
+
+> Personally I would be willing to take the plunge here, and
+> admit that a horrible mistake had been made, and that if an
+> exception propagates out of a task, the entire program is
+> terminated in an implementation dependent manner, as we do
+> for the environment task.
+
+That's an interesting idea, especially from someone who is usually
+opposed to any kind of incompatibility ;-)  I agree that it should have
+been that way in the first place, and I would be willing to byte the
+bullet and accept the incompatibility.  (Of course, as others have
+noted, "program" should be "partition" above.)
+
+Bob wrote (acting as a spokesman for Tuck):
+
+> ... E.g., task A invokes task B, and Tuck wants
+> to put code in task A that protects it from bad behavior of task B. He
+
+> doesn't want to put code in task B, because maybe it comes from an
+> outside organization or is somehow untrustworthy or whatever. That
+> view makes some sense, although if task B starts doing Unchecked_Conv
+> of pointers, all bets are off.
+
+If you put untrustworthy code in a high-integrity system, you have other
+problems than task termination ;-)
+
+Seriously, I fail to see how the proposal deals with this situation.
+Deep inside the guts of some subsystem provided by an outside source
+there is a task B.  How the hell do I establish a termination handler
+for this task?  Establishing a handler requires a Task_ID.  How do I get
+a Task_ID?  If task B is not visible, and if it's not particularly
+cooperative (i.e., it doesn't export an operation that returns its own
+Task_ID) you are out of luck.
+
+If you don't have the source of this outside subsystem, btw, you may not
+even know if it's doing tasking, or using some other kind of parallelism
+(playing with interrupts, accessing the thread library directly, etc.).
+Hey, this can even change from one version to the next.
+
+If all the code is under your control, true, you can export the
+appropriate information.  But then I agree with Robert and Bob  that you
+are probably going to program the interactions between tasks carefully,
+and that you can do all the necessary termination control within the
+current language.
+
+--
+
+I have another concern with this proposal: it seems very convoluted to
+me.  Implementation-wise, I am not competent: from 30,000 ft this is
+just another piece of junk in the TCB and just another thing to do at
+termination.  However, the conceptual model is very intricate: each time
+this AI has been discussed by the ARG it has taken a lot of efforts to
+re-explain the notion of default handler and specific handler, and how
+these handlers are set from the outside, and why, etc.  It is
+significant that we changed the identifiers _each_time_ we discussed
+this AI, and I still don't find them very expressive.
+
+Now if the ARG has trouble grappling with this AI, I cannot imagine how
+the average Ada user can be expected to do anything useful with it.
+Especially considering that pretty much the same effect can be
+programmed using the current language.  Furthermore, it seems to me that
+this feature could be easily misused or abused, as it would introduce
+lots of coupling between the parts of a system.  This is particularly
+hard to manage in large programs.
+
+To summarize, I'd say: who ordered this?
+
+****************************************************************
+
+From: Robert A. Duff
+Sent: Friday, February 13, 2004  8:05 AM
+
+Randy wrote:
+
+> The AdaIC web server has never failed to service web requests because of a
+> software problem, so far as I'm aware. (It's been clobbered by Windows, by
+> long power failures, by our ISP, and by SBC, but never by an Ada
+> program-related bug). That's in part because any tasks that raised
+> exceptions and failed while trying to log that fact simply go away instead
+> of terminating the program. (I can't say whether this actually has happened;
+> by definition, such a failure would not be logged.)
+
+This is a very good point, which I had forgotten.  It's all well and
+good to tell programmers to put a handler at the bottom of their tasks.
+But what if that handler raises exceptions?
+
+Ideally, you would prove that the handler itself can't raise
+exceptions.  But Ada doesn't have any built-in support for that.
+
+>  This is a special problem if the exception is
+> Storage_Error from running out of stack space, because any attempt to do
+> anything is going to re-raise the exception.
+
+I claim Storage_Error is hopeless anyway -- in Ada it is impossible to
+write a handler for Storage_Error that does anything interesting (at
+least, not without implementation-specific hackery).  Not even print an
+error and shut down the program, much less to log the error and
+continue.
+
+****************************************************************
+
+From: Robert A. Duff
+Sent: Friday, February 13, 2004  8:25 AM
+
+Alan wrote:
+
+> So would the following be sufficient:
+>
+> As part of task termination, but before any local objects are
+> finalised, the task specific handler ...
+
+I agree with Tucker, who said that you want the task specific handler to
+run *after* all objects local to the task have been finalized.
+
+The wording is tricky.  I don't think we can say "as part of task
+termination", because termination is not a process.  9.3(5) defines
+termination -- a task is terminated when finalization of the task_body
+has been performed.  A task_body is a master, and finalization of it
+means waiting for dependent tasks, then finalizing all the objects in
+it.  So I think what we want is to make the task specific handler run as
+part of finalization of a task_body -- after finalizing the objects.
+
+How about this: "As part of the finalization of a task_body, after
+performing the actions specified in 7.6.1 for finalization of a master,
+the task specific handler is called."  Then AARM annotations can point
+out that this means that 'Terminated is False while running the
+handler, but that all objects local to the task have been finalized.
+I think this also implies that Current_Task is the task in question.
+
+****************************************************************
+
+From: Jean-Pierre Rosen
+Sent: Friday, February 13, 2004  9:03 AM
+
+> The implementation could use finalization to accomplish
+> this, but it should be after all user-defined finalization,
+> since those might themselves raise exceptions.
+
+OTOH, a task may define one of its own internal procedures as a termination
+handler, and thus access its own finalizable objects. Minimizing accesses to
+objects after they've been finalized seems desirable...
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Friday, February 13, 2004  10:53 AM
+
+> OTOH, a task may define one of its own internal procedures as a termination handler,
+> and thus access its own finalizable objects.
+
+No, the handler is required to be library-level, I believe, or at the very
+least, something that outlives the tasks it is handling.
+
+> Minimizing accesses to objects after they've been finalized seems desirable...
+
+Yes, but we don't allow "local" handlers.
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Friday, February 13, 2004  10:51 AM
+
+Pascal Leroy wrote:
+>
+> That's an interesting idea [killing partition due to exception
+> killing task body], especially from someone who is usually
+> opposed to any kind of incompatibility ;-)  I agree that it should have
+> been that way in the first place, and I would be willing to byte the
+> bullet and accept the incompatibility.  (Of course, as others have
+> noted, "program" should be "partition" above.)
+
+I reply again (because I saw no acknowledgement or response to this):
+
+... Ada provides ways *within* the language to
+handle errors, even really "bad" ones.  It is not uncommon
+to have exception handlers at an outer level whose job it
+is to catch unexpected exceptions, and reset the
+state in some way, drop back to a reduced functionality, shut
+down gracefully.  Why should this particular error (an unhandled
+exception in a task body) go outside of the language, providing
+no way to handle it at a higher level?
+
+That's not the Ada way, and is bad news for long-running,
+at least semi-fault-tolerant software, like a server or
+a control system.
+
+---
+
+I agree the solution should be well-defined, and not overly complex.
+But I think the task hierarchy should be obeyed (that is,
+a task can control its subtasks).  I believe setting an overall default
+handler within a hierarchy is more important than setting handlers
+for individual tasks, and if it would significantly simplify
+the proposal to omit individual task handlers, then let's consider it.
+But I believe some way of handling unexpected task termination (*within
+the language*) is quite important, and has been a well-known hole in
+Ada since early on.
+
+****************************************************************
+
+From: Gary Dismukes
+Sent: Friday, February 13, 2004  12:43 PM
+
+I find your arguments convincing and am in favor of providing
+some mechanism to address this.  I think we should consider
+possible simplifications based on an overall hierarchy handler,
+but see value in the per-task termination handling capability
+and would prefer that if it can be kept reasonably simple.
+
+****************************************************************
+
+From: Alan Burns
+Sent: Wednesday, February 18, 2004  7:22 PM
+
+To summaries recent emails. 3 questions seems to relevant.
+
+Do we want this functionality
+Do we want something simpler
+If we do want something, exactly what are the semantics.
+
+To deal with the last point first. There seems general
+agreement that the handler should be called after the
+finalisation of local objects. Bob suggests the following
+words:
+
+As part of the finalization of a task_body, after
+performing the actions specified in 7.6 for finalization of a master,
+the task specific handler is called. ...
+
+Anyone not happy with this?
+
+
+With regard to the other questions
+Pascal asked "who ordered this".
+There seems to be a few different groups. The main
+request came from real-time ravenscar folk, who wanted
+a standard way of dealing with terminating tasks (under
+Ravenscar no task should terminate). The action to be
+taken would usually be a shut-down or restart or lane
+switch (and restart), ie fault recognition
+within the program, but no recovery within the program.
+
+More general fault tolerance folk see a way of programming
+some forms of recovery. If task T fails then create a new task
+(non-determinacy is likely to stop this new one failing
+at the same point, ie new input data, different internal
+state), or create a different task (different type) but
+with reduced functionality.
+
+These two requirements both seem reasonable. I'm less
+convinced by the "fault in some external subsystem" argument.
+What can the programmer do?
+
+I do not think the original semantics are wrong. The task is
+a natural fault containment unit. Within a task an exception
+is synchronous. To raise an exception within the parent/master would
+be asynchronous and error prone. Remember the debate about
+select then abort, rather than asynchronous exceptions.
+The current proposal allows the handler to be independent of
+parent task or (via the use of a PO and ATC) to gain the
+attention of the parent in a controlled way. Tuck argues:
+
+> ... Ada provides ways *within* the language to
+> handle errors, even really "bad" ones.  It is not uncommon
+> to have exception handlers at an outer level whose job it
+> is to catch unexpected exceptions, and reset the
+> state in some way, drop back to a reduced functionality, shut
+> down gracefully.  Why should this particular error (an unhandled
+> exception in a task body) go outside of the language, providing
+> no way to handle it at a higher level?
+>
+> That's not the Ada way, and is bad news for long-running,
+> at least semi-fault-tolerant software, like a server or
+> a control system.
+>
+> ---
+>
+> I agree the solution should be well-defined, and not overly complex.
+> But I think the task hierarchy should be obeyed (that is,
+> a task can control its subtasks).  I believe setting an overall default
+> handler within a hierarchy is more important than setting handlers
+> for individual tasks, and if it would significantly simplify
+> the proposal to omit individual task handlers, then let's consider it.
+> But I believe some way of handling unexpected task termination (*within
+> the language*) is quite important, and has been a well-known hole in
+> Ada since early on.
+
+The current proposal could be simplified by removing the specific
+handler and just have the default. This would be fine for ravenscar.
+
+I will be interested to see what the vote is at the next meeting!
+
+****************************************************************
+
+From: Robert Dewar
+Sent: Thursday, February 19, 2004  6:31 AM
+
+Pascal Leroy wrote:
+
+<<much excellent discussion snipped>>
+
+> To summarize, I'd say: who ordered this?
+
+I 100% agree with everything Pascal said here.
+
+****************************************************************
+
+From: Robert Dewar
+Sent: Thursday, February 19, 2004  7:06 AM
+
+> ... Ada provides ways *within* the language to
+> handle errors, even really "bad" ones.  It is not uncommon
+> to have exception handlers at an outer level whose job it
+> is to catch unexpected exceptions, and reset the
+> state in some way, drop back to a reduced functionality, shut
+> down gracefully.  Why should this particular error (an unhandled
+> exception in a task body) go outside of the language, providing
+> no way to handle it at a higher level?
+
+Actually in critical software, these "standard" mechanisms
+are often not used. Why not? For several reasons:
+
+   exception handling is complex, and something that you
+   usually want to exclude from the certification arena.
+
+   if you do have exceptions, then they raise annoying
+   testing issues and deactivated code issues, noticeably
+   raising the costs of handling them.
+
+   generally you DO try to prove that exceptions are
+   not possible (see praxis site for an interersting
+   example of this approach carried all the way).
+
+   exceptions are not really the right model anyway
+   for handling disastrous errors requiring a system
+   reset. They can get swallowed up by others handlers,
+   or by task termination (the current discussion) or
+   propagating them can simply hang due to waiting for
+   tasks to terminate.
+
+So generally the more common model is to see some kind
+of last chance handler that is most definitely outside
+the language.
+
+Now this is certainly not always the case, and in fact
+we have a major customer doing certification who needs
+a limited form of general exception handling to deal
+with some legacy code. This will indeed result in
+increases in certification costs, and we will have to
+be very careful the above problems do not arise!
 
 ****************************************************************
 

Questions? Ask the ACAA Technical Agent