Ayk96
Ayk96

Reputation: 79

Ada stop entry execution and execute other entry

I'm new to Ada and I'm trying to write a simple program but I have some issues I couldn't solve. So I have a task with an execute entry and a signalfound entry, the execute entry is being called first and has to do some calculations until the signalfound entry is being called by the main and then it has to stop.

But the problem is that when Signalfound entry is called it doesn't get executed because the task is stuck in the while loop. Is there an obvious solution to this problem in Ada. I tried googling the problem but without succes. Thanks in advance!

task Example body
  ResultFound : Boolean := False;
  --- other unimportant things
begin
  loop
    select
       accept Execute do
         while (ResultFound = False) loop
             ---do some calculations
         end loop;
       end Execute;
    or
       accept SignalFound do
         ResultFound := True;
       end SignalFound;
    or
       -- other unimportant accepts
    end select;
  end loop;
end Example;          

Upvotes: 1

Views: 125

Answers (1)

flyx
flyx

Reputation: 39738

Well, when Execute is called, your task enters the loop, which means it never executes the select statement again, so it can never accept the SignalFound call. Also, the entity calling Execute will never continue since your while loop repeats forever inside the accept statement. Usually, you want to make your critical regions for task synchronisation as small as possible, so that both tasks can carry on with their work after necessary data has been exchanged.

Mind that your code reflects a protocol by which your task operates. Currently, your code says „I will accept both Execute and SignalFound at any loop iteration“, which does not seem to match with the protocol you have in mind based on what you write.

I believe what you actually want to do is something like this:

task Example body
begin
  loop
    --  simply wait for someone to tell me to execute.
    accept Execute;

    Calculations : loop
       --  check at every loop iteration whether there's a SignalFound waiting
       select
          accept SignalFound;
          exit Calculations;
       else
          -- do some calculations
       end select;
    end loop Calculations;

    -- will go to next iteration and wait for someone to call Execute again.
  end loop;
end Example;

This code enforces a sequence of alternating Execute / SignalFound calls which seems to be what you have in mind.

Upvotes: 3

Related Questions