On 04-May-01 adam@irvine.com wrote: > My second question about protected objects and requeueing: > > 9.5.2(31) says that although you can't use a formal parameter in an > entry barrier, but need to look at the parameters before deciding If the parameter to be put into the entry barrier has just a few different values, a family entry would solve the problem. The family parameter may be used in the barrier. > whether to handle it, "the entry_barrier can be 'when True' and the > caller can be requeued (on some private entry) when its parameters > indicate that it cannot be handled immediately." > > Although this makes sense intuitively, I'm having trouble figuring out > how it would work in a seemingly simple case. Suppose I have a > protected object that looks like this: > > protected PR is > entry E1 (Min_Count : in integer; Result : out integer); > procedure PROC1; > private > Count : integer := 0; > end PR; > > Suppose PROC1 increments Count. The intent of E1 is for each calling > task to wait until Count has been incremented past whichever point > that task desires. This is illegal: > > entry E1 (Min_Count : in integer; Result : out integer) > when Min_Count >= Count is ... > > Intuitively, it seems like this should work: > > entry E1 (Min_Count : in integer; Result : out integer) when True is > begin > if Min_Count < Count then > requeue E1; > end if; > Result := ... > > with the intended effect being that after PROC1 is called, all the > entries on E1 will be executed to check their Min_Count, and those > that don't meet the requirement will requeue themselves, while those > that do will complete. > > But I don't think it works. As I read 9.5.3, it seems that when E1 > requeues itself, the protected action continues, and this includes > servicing entry queues, and since "servicing of entry queues continues > until there are no open entries with queued calls" (9.5.3(18)), but > this entry will always be open and there will always be a queued call > on it, since the task keeps requeueing itself on the entry. Thus, the > result of this is an infinite loop. > > I recognize that 9.5.2(31) suggests using a private entry, but I'm not > sure how. If the barrier on the private entry is "when True", the > same problem occurs; but I can't think what other barrier could be put > on the private entry to make things work. You could copy the attribute COUNT of the private entry to a variable "How_Many_To_Go" of the protected type in PROC1 and use "How_Many_To_Go>0" as the barrier of the private entry; it�s body should decrement the variable. But using the COUNT attribute is like walking on thin ice. (Think about aborts and timed entry calls.) _And_ You will need a "Pragma Queuing_Policy (FIFO_Queuing)" I like it more to use two private entries which requeue to each other and open alternating -- switching occurs every time PROC1 is called. As both of them have the same code and switching reduces to setting a variable, a family of two entries is handy. You can also use "requeue with abort" here without running into problems. (I hope someone will intervene, if I�m telling wrong or misleading things.) Wilhelm