!topic LSN on Requeue Statements Simplifications !key LSN-1048 on Requeue Statements Simplifications !reference MS-9.7.1;4.6 !from Bob Duff $Date: 92/10/14 14:25:05 $ $Revision: 1.3 $ !discussion This Language Study Note discusses certain simplifications of requeue statements that have been considered by the MRT. At the Frankfurt WG9 meeting in April, the consensus was that the requeue statement should be supported in Ada 9X. However, it was also suggested that the MRT study simplifications of the requeue statement. Although requeue is quite powerful in its support of preference control, the semantics are fairly simple already. It allows a currently executing entry call to be completed, but instead of returning, to be placed on another entry queue. However, there are some options; the simplifications that were suggested were: (1) to remove the ability to say "with abort", and (2) to disallow one or more of the combinations of task-entry and protected-entry that are allowed. We consider each of these in turn. WITH ABORT. The requeue statement currently has an option: the requeue can be without abort (the default), or with abort. Without abort means that the caller is in an abort-deferred state while waiting on the new queue, just as if an accept statement or entry body were in progress. With abort means that the caller can be aborted during that time, as for the initial entry call queuing. These correspond to two situations where preference control is needed: The without abort case is the simplest to program, since the server can assume that once a given operation has started, it will complete. A task that has been requeued will still be there when the time comes. This means that the server can freely set up data structures that represent the request being serviced, and not worry about those data structures being invalid in case the caller disappears. The with abort case is needed when the server wishes to allow the caller to be aborted or cancelled in the middle of the operation. This is more complex to program: the server must be able to recover in case the caller disappears after having been requeued. However, this extra complexity is necessary in certain applications. In particular, if the time during which the caller might be requeued is long and/or unbounded, a real-time program cannot simply wait forever. Another way to look at it is that if the server does not do much at the initial step, but merely determines the appropriate queue to place the caller on (as in the disk server example), then from the point of view of the caller the service has not started yet. It seems from the above that both with and without abort are needed in real applications. Since the added complexity of having the option is relatively minor (both in semantic terms and in implementation terms), it is well worth it. It is interesting to note that when people have suggested getting rid of one of the options, and we have asked people which one should remain, some say "with abort" and some say "without abort". This makes it rather difficult to decide which of the two should be the only possibility in Ada 9X. I think this difficulty is a symptom of the fact that in some cases with abort is needed, and in other cases, without abort is needed. The fact that one feature can solve two nearly unrelated kinds of problems is a benefit. Thus, we have chosen to keep both possibilities in the language. TASK ENTRY/PROTECTED ENTRY COMBINATIONS. There are four combinations of requeue that make sense: from task to task, from task to protected object, from protected object to task, and from protected object to protected object. However, even before the above-mentioned WG9 meeting, we had recognized that one of these combinations is not very useful, and is particularly difficult to retro-fit into existing implementations. That combination is the protected-entry-to-task-entry case, and has been disallowed for some time. The other three combinations are currently allowed. Clearly, the task-entry-to-task-entry case and the protected-entry-to-protected-entry case are easy to implement, and are necessary. Removing the former would make tasks second-class citizens. Removing the latter would require the use of tasks instead of protected objects, thus defeating an important use of protected objects. Anyway, nobody has specifically suggested removing these two. It was suggested, however, to disallow the task-entry-to-protected-entry case, probably out of some sense of symmetry -- if this case were removed, then both mixed cases would be illegal. However, the one illegal case is illegal because it was found to be difficult to implement, not because it doesn't make sense. This implementation difficulty in no way reflect on the usefulness (or implementation difficulty) of the symmetric case. In fact, the task-entry-to-protected-entry has been found to be quite useful. It is used in cases where the server is a task, but wants to "park" callers somewhere until some condition is true. We do not wish to make protected records completely out of reach of such code, requiring tasks for temporary requeuing. SUMMARY: We have decided not to simplify the requeue statement any further. It is already fairly simple semantically and reasonably easy to implement. We believe that the restrictions that have been suggested are arbitrary restrictions that simplify neither the programmer's nor the implementer's job. As always, we are open to suggestions for further simplification. However, adding arbitrary restrictions does not seem at this point to be a fruitful approach.