!standard 11.6(5) 06-12-14 AI05-0030-1/00 !class Amendment 06-03-21 !status work item 06-03-21 !status received 06-03-03 !priority Medium !difficulty medium !subject Requeue on sychronized interfaces !summary (See proposal.) !problem ** See Alan's mail ** !proposal [Allow requeues on primitive procedures of synchronized interfaces. For a requeue on a real procedure (not an entry), raise Program_Error? Just call the procedure? Fall over dead? ;-)] !wording (** TBD **) !discussion ** TBD ** !example ** Hopefully Alan will send one someday ** !ACATS test Create an ACATS test to check that the above changes work. !appendix From: Alan Burns Sent: Friday, October 13, 2006 5:54 AM Andy and I have been developing some real-time 'patters' for common idioms; for example periodic tasks with deadline overrun detection and budget rationing. We can do this in quite an abstract way by the use of task, protected and synchronized interfaces. However, we have come across a couple of situations where we want to requeue to another entity and the inability to 'requeue to a procedure' has impacted on the expressive power of what we are trying to do. When task, protected and synchronized interfaces were introduced the provision was made to be able to make a timed call on an interface procedure. I believe it was a simple omission for Ada 2005 to fail to allow requeues on interface procedures. Is there anyway of putting this omission right? The language rules would seem to be straightforward - if the 'procedure' was not implemented as an entry then an exception should be raised at the point of the requeue. To give a simple example: Given: type Server is synchronized interface; procedure Register(S: in out Server) is abstract; type Any_Server is access all Server'Class; We now define: protected type X(S : Any_Server) is entry Y; end X; protected body X is entry Y when True is begin requeue S.Register; end end X; You know that S must be a task or a PO. Consequently, this would seem to us to be a valid thing you would want to do (ie requeue to S.Register). **************************************************************** From: Pascal Leroy Sent: Friday, October 13, 2006 6:26 AM > The language rules would seem to be straightforward - if the > 'procedure' was not implemented as an entry then an exception > should be raised at the point of the requeue. Is there any reason why you want to raise an exception in this case? In all the other cases where some "procedure" may or may not be an entry we defined some reasonable semantics that doesn't involve exceptions. Why would requeue be different? My concern is that users would have to handle predefined exceptions in order to prevent their code from dying if the procedure is not implemented by an entry. This doesn't seem right. **************************************************************** From: Tucker Taft Sent: Friday, October 13, 2006 7:25 AM One of the issues with requeue is that the semantics are relatively tightly tied to there actually being a queue on which to place the entry call, since the requeue may be executed by an entry body that is being run on some "convenient" thread. You probably wouldn't want to allow the requeue to involve invoking synchronously an arbitrarily complicated procedure with possibly multiple nested blocking actions. That works OK at an original call point, but for a requeue, it would not work in any straightforward way. Requeue pretty explicitly specifies the presence of a queue, and if there isn't one, raising an exception seems like about the only recourse. **************************************************************** From: Alan Burns Sent: Friday, October 13, 2006 7:57 AM Yes this was our conclusion, fundamental to requeue is that control passes from the current context. When the entry is completed, control does not return to the point of the requeue, so executing the procedure and returning does not seem right. An exception seems like the right action as tuck says **************************************************************** From: Pascal Leroy Sent: Friday, October 13, 2006 7:44 AM I understand, but given that (1) we are not capable of defining proper semantics in the case where the procedure is not an entry and (2) we have no way to specify on the interface that the procedure has to be implemented by an entry, I conclude that the entire idea is a bad violation of the Substitution Principle and that it is a good thing that requeue-through-interfaces are disallowed. **************************************************************** From: Tucker Taft Sent: Friday, October 13, 2006 8:56 AM I was concerned about the same thing, and so I was very interested in seeing realistic examples. I believe that Alan and Andy came up with several. Once you start using polymorphism with tasking, it seems inevitable that if you do an "external" requeue, you will want to be able to do it through an interface. Perhaps we need some way of requiring a procedure to be implemented by an entry? We could make it an optional pragma (analogous to pragma Convention) which if absent, leaves open the possibility of a run-time exception, but if present, ensures that no run-time exception would occur at the point of requeue. Adding new syntax is of course a possibility, but then this no longer looks like a "binding interpretation" style of AI, but rather clearly an amendment. Alternatively, we figure out a way to implement this by treating a procedure as equivalent to an entry with a "true" barrier, and have a pseudo "queue" created as needed upon invocation of the requeue. This latter approach seems to require more implementation work and more tricky wording. My conclusion was that there *was* an oversight in this area, and the "simple" solution of raising an exception would be sufficient for a quick fix, but that next time we get into "amendment" mode, we could work out a more sophisticated model, while remaining effectively compatible with this simple exception-raising approach. Admittedly not ideal, but I hate to "orphan" requeue as we move into a polymorphic synchronization world. **************************************************************** From: Pascal Leroy Sent: Friday, October 13, 2006 9:49 AM > I was concerned about the same thing, and so I was very > interested in seeing realistic examples. I believe that Alan > and Andy came up with several. Once you start using > polymorphism with tasking, it seems inevitable that if you do > an "external" requeue, you will want to be able to do it > through an interface. I would certainly like to see realistic examples, if Alan is willing to share them with the rest of us. > Perhaps we need some way of requiring > a procedure to be implemented by an entry? That might be a nice extension in the future, but I think we first want to see synchronized interfaces used in real life. And we are not in amendment mode anymore. > Alternatively, we figure out a way to implement this > by treating a procedure as equivalent to an entry with > a "true" barrier, and have a pseudo "queue" created > as needed upon invocation of the requeue. This latter > approach seems to require more implementation work > and more tricky wording. I still don't understand what would be wrong with the following: if the procedure is not an entry, the requeue statement calls the procedure, and when the procedure returns it immediately leaves the enclosing accept statement or entry body. True, the procedure called that way could do all sorts of nasty things like potentially blocking operations, but this is a general danger with dispatching calls. At least with such a scheme the user could give a reasonable semantics to the call if they so desire (or they could raise an exception in the classes that don't implement the procedure as an entry). **************************************************************** From: Tucker Taft Sent: Friday, October 13, 2006 9:58 AM Another way to view this requeue restriction would be to think of it as similar to the rules that forbid calling a potentially blocking operation from inside a protected operation. I.e.: If you *call* a procedure through a synchronized interface from inside a protected operation, if the procedure turns out to be implemented (directly or indirectly) via an entry, then that would be violating the no-potentially-blocking rules. If you *requeue* on a procedure through a synchronized interface then you would get an exception if it is *not* an implemented by an entry. There seems a pretty close analogy, where you have to have some knowledge of how the procedure of a synchronized interface is implemented to know whether to call or to requeue. If you are wrong in either way, you could get Program_Error at the point of the call/requeue. **************************************************************** From: Tucker Taft Sent: Friday, October 13, 2006 10:05 AM > I still don't understand what would be wrong with the following: if the > procedure is not an entry, the requeue statement calls the procedure, and > when the procedure returns it immediately leaves the enclosing accept > statement or entry body. True, the procedure called that way could do all > sorts of nasty things like potentially blocking operations, but this is a > general danger with dispatching calls. At least with such a scheme the > user could give a reasonable semantics to the call if they so desire (or > they could raise an exception in the classes that don't implement the > procedure as an entry). Those semantics don't seem too bad to me. As you say, if the procedure involves a blocking operation, you are in trouble and will possibly get a Program_Error If it doesn't, then you are OK. But I also think my message that crossed in the e-mail with yours provides some justification for raising Program_Error at the requeue point. I could go either way. If we do want it to "work" when requeuing on a procedure, I agree yours is the more straightforward implementation model. **************************************************************** From: Alan Burns Sent: Friday, October 13, 2006 11:49 AM Andy and I can produce some examples - but not immediately as I am about to go off traveling for a week, by which time I'm sure Pascal and Tuck will have agreed on the right language model! We were concerned with the implementation overhead of anything other than raising an exception. **************************************************************** From: Robert A. Duff Sent: Friday, October 13, 2006 3:41 AM A protected procedure is a lot like an entry with an always-True barrier. Therefore, I agree with the following: > I still don't understand what would be wrong with the following: if the > procedure is not an entry, the requeue statement calls the procedure, and > when the procedure returns it immediately leaves the enclosing accept > statement or entry body. **************************************************************** From: Randy Brukardt Sent: Friday, October 13, 2006 6:25 PM Alan Burns wrote: ... > When task, protected and synchronized interfaces were introduced the > provision was made to be able to make a timed call on an interface > procedure. I believe it was a simple omission for Ada 2005 to fail > to allow requeues on interface procedures. Is there anyway of putting > this omission right? I don't want to comment on whether or not it is a good idea, but this was not "a simple omission". We specifically considered whether we wanted to allow requeue at the Paris meeting (Feb. 2005), and rejected the idea. The minutes of that meeting say (under AI-397): "Steve Baird asks if you can requeue on a synchronized procedure. No, we don't allow that, because the synchronized procedure doesn't necessarily denote an entry. And what such a requeue would do if the procedure wasn't an entry is rather unclear." (My memory was that there was more issues beyond the one recorded, but since I don't remember any details, at this point that would be just FUD.) I can imagine that new information could make it worthwhile to make a different decision on requeue, but not having it was certainly *not* an omission. It was completely intentional. As such, I think we would have to classify this as an Amendment (I don't think "we changed our mind" is a legitimate reason to classify something as a bug)! Personally, I think requeueing to a procedure makes no sense at all, and thus Program_Error seems to be appropriate. It is already devilishly hard to implement (external) requeue, and this will be worse -- I don't see much reason to try hard to make useless cases work. I'd like to see a real example, too. Not that I doubt that Alan has one, but it would be valuable to get it on the record and try to judge its importance. Especially if we want to lie about this being a bug -- in that case, I think it had better be quite important. **************************************************************** From: Alan Burns Sent: Tuesday, November 14, 2006 2:32 AM I note the following on the agenda. >Requeue on synchronized interfaces [AI not made yet.] After I raised this point about requeue on interfaces Randy noted that this was not an 'omission' but a clear decision at some meeting or other not to allow requeue. Hence I assume the issue is closed. However if the ARG is at least open to consider this topic I will produce an AI for a future meeting. If the current meeting has time to at least decide if such an AI is 'in scope' I would appreciate it. **************************************************************** From: John Barnes Sent: Wednesday, November 22, 2006 2:01 AM It was suggested at the meeting last weekend that the topic should be considerd by the next IRTAW in Vermont and then reported back to the ARG in Geneva. ****************************************************************