emery@gypsy.UUCP (06/04/86)
I think you are asking "Why don't exceptions propogate out of tasks?" If so, don't feel bad, I asserted that they do once in public, and was quickly corrected. Exceptions do not propogate out of tasks. If a task raises an exception that it doesn't handle, the task becomes 'completed', but no further action (including propogating the exception) takes place. Quotes from the Canon: Ada RM, section 11.4.1 "If an exception is raised in the sequence of statements of a frame that does not have a handler for the exception, execution of the sequence of statements is abandoned. The next action depends on the nature of the frame: (a) For a subprogram body, the same exception is raised again at the point of call of the subprogram, unless the subprogram is the main program itself, in which case execution of the main program is abandoned. (b) For a block statement, the same exception is raised again immediately after the block statement (that is, within the innermost enclosing frame or accept statement). (c) For a package body that is a declaritive item, the same exception is raised again immediately after this declarative item (within the enclosing declarative part). If the package body is that of a subunit, the exception is raised again at the place of the corresponding body stub. If the package is a library unit, execution of the main program is abandoned. (d) For a task body, the task becomes completed. An exception that is raised again (as in the above cases (a), (b), (c)) is said to be propogated, either by the execution of the subprogram, the execution of the block statement, or the elaboration of the package body. No propogation takes place in the case of a task body. If the frame is a subprogram or a block statement and if it has dependent tasks, the propogation of an exception takes place only after termination of the dependent tasks. Finally, if an exception is raised in the sequence of statements of an exception handler, execution of this sequence of statements is abandoned. Subsequent actions (including propogation, if any) are as in the cases (a) to (d), above." So, here's an interesting design problem: How does a task report failure due to an exception to its parent? Dave Emery Siemens Research UUCP: ...princeton!siemens!emery ARPA: princeton!siemens!emery@topaz.rutgers.edu
Bryan@SU-SIERRA.ARPA (Doug Bryan) (06/06/86)
Dave, also, don't forget that if an execption is raised during a rendezvous, it is raised in the task being called and propagated to the calling task as well. doug -------
emery@gypsy.UUCP (06/06/86)
Both Frank Prindle and Doug Bryan have reminded me that, should an exception be raised during rendeveous, the exception is propogated to BOTH tasks. This is perfectly consistent with the notion that the rendeveous code is run 'by both tasks'. However, exception propogation, once inside the two tasks, follows the rule I cited, i.e. the exception is not propogated out of either task. Thanks, guys. On a related topic: A command interpreter is one good example of a program that may be called to invoke other programs, which are not known at compile time (see Tom Wheeler's article, cited in previous discussions.) If you presume that all such 'programs' are tasks, here's my design problem again: How does a task report failure to its parent. One of the problems here is the task name problem. A task does not know its identity, therefore it cannot say things like "I am task 36, and I aborted because of a fubar exception." The standard way around this is to "christen" the task through an entry call, where the caller tells the task its name ("You are task 36"). It seems that a task identity scheme is a necessary condition for having tasks report their failure. Dave Emery Princeton Research UUCP: ...princeton!siemens!emery ARPA: princeton!siemens!emery@topaz.rutgers.edu or @seismo.css.gov
Brosgol@MIT-MULTICS.ARPA (06/09/86)
With respect to some recent interchanges on exception propagation and tasks... Long ago and far away there was a mechanism in Ada known as the 'FAILURE exception. It was an attribute of a task, and the idea was that by raising FOO'FAILURE you could let task FOO carry out its "last wishes" before its demise. Kind of a graceful abort. Well, it was nice in theory but proved to be devilish in practice -- it turned out to be impossible to program task FOO so that it could respond to an exception that was raised asynchronously. So 'FAILURE is now an archeological curiosity rather than a language feature. The problems with asynchronous exceptions are why exceptions do not propagate out of tasks. That is, there is no way of knowing where the parent task is when the child task raises the exception. Asynchronous exception raising would be an unreliable and hard to implement means of synchronization. So, sorry about the lack of symmetry between tasks and other units with respect to exception propagation, but tasks are different in an essential way here. If a task must communicate its failure to complete normally, then it should do so via the recommended synchronization technique -- rendezvous. (If you like to live dangerously and erroneously I guess you could also use shared variables.) If it is important for a parent task to know that its children have completed successfully, then the parent should rendezvous with each child when it (the parent) has finished its own business. Make sure that each child has a "when others ==> accept DONE(...)" where DONE has an out parameter that reflects the child's status. Each child must also accept DONE when it completes normally. The program invocation example mentioned by Dave Emery looks like a red herring as far as the exception propagation issue is concerned. Program invocation does not follow Ada tasking semantics (the invoked program and the invoker have no common address space, and the invokee is not a child task of the invoker -- the invoker does not sit suspended waiting for the invokee to complete). So I don't see that it is relevant to the issue of whether exceptions should or shouldn't propagate. -Ben Brosgol