2017-09-07 8 views
1

Je suis à la recherche d'un moyen de sélectionner plusieurs entrées. J'ai la tâche suivante et sélectionnez le bloc. L'intention est d'exécuter plusieurs (2) tâches ailleurs, exécutez jusqu'à ce qu'un terminée, ou délai d'attente après un certain laps de tempsAda sélectionnez plusieurs entrées

task type t_startup_task is 
    entry start; 
    entry started; 
end t_startup_task; 

task body t_startup_task is 
    startup_sig : Boolean := False; 
begin 
    accept start; 
    busy : loop -- wait for external flag to become true 
     status.read_signal (startup_sig); 
     if startup_sig then 
     exit busy; 
     end if; 
     delay 0.1; 
    end loop busy; 
    accept started; 
end t_startup_task; 

<...> 

startup_task.start; 
select 
    startup_task.started; 
or 
    state.wait_done; -- other entry 
    abort startup_task; 
    return False; 
or 
    delay 4.0; 
end select; 

Cependant, il en résulte l'erreur de compilation suivante:

only allowed alternative in timed entry call is delay 
"or" not allowed here 

Quelle est la meilleur moyen de le faire réellement?

Répondre

3

Malheureusement, vous ne pouvez pas utiliser une instruction select pour décider entre plusieurs appels d'entrée. Vous pouvez cependant les utiliser pour choisir entre accepter des entrées, donc une implémentation avec trois tâches devrait fonctionner.

Vous pouvez toujours avoir votre valeur de retour en utilisant un paramètre out sur l'appel d'entrée final.

task startup_task is 
    entry start; 
    entry wait_done; 
    entry signalled; 
    entry started (success : out boolean); 
end startup_task; 

-- This task waits upon your other entry, then calls the startup_task 
-- entry once it has completed 
task startup_wait is 
    entry start; 
end startup_wait; 
task body startup_wait is 
begin 
    accept start; 
    state.wait_done; 
    startup_task.wait_done; 
end startup_wait; 

-- This task contains your busy loop and calls the startup_task 
-- entry once it has completed 
task startup_signal is 
    entry start; 
end startup_signal; 
task body startup_signal is 
begin 
    accept start; 
    busy : loop -- wait for external flag to become true 
     status.read_signal (startup_sig); 
     if startup_sig then 
      exit busy; 
     end if; 
     delay 0.1; 
    end loop busy; 
    startup_task.signalled; 
end startup_signal; 

-- This task provides the functionality of your invalid select statement, 
task body startup_task is 
    success : boolean := False; 
begin 
    -- These start signals ensure that the subtasks wait for synchronisation 
    accept start; 
    startup_wait.start; 
    startup_signal.start; 
    select 
     accept signalled; 
     abort startup_wait; 
     success := True; 
    or 
     accept wait_done; 
     abort startup_signal; 
    or 
     delay 4.0 
     abort startup_wait; 
     abort startup_signal; 
    end select; 
    accept started (success); 
end startup_task; 

<...> 

result : boolean; 
begin 
    -- this block replaces your invalid select statement 
    startup_task.start; 
    startup_task.started(result); 
    return result; 
end; 

Remarque, je n'ai pas testé ou compilé ce code, mais il devrait donner une idée pour une solution.

0

Techniquement, la langue permet ceci:

select 
    delay 4.0; 
    ... 
then abort 
    select 
     Entry1; 
     ... 
    then abort 
     Entry2; 
     ... 
    end select; 
end select; 

qui pourrait faire ce que vous voulez. Cependant, la meilleure façon est sans doute d'avoir les tâches vérifier avec un objet protégé, et attendre sur une entrée de la PO:

protected Multi_Wait is 
    procedure Task1_Ready; 
    procedure Task2_Ready; 
    entry Wait_For_Either (Task_1 : out Boolean; Task_2 : out Boolean); 
private -- Multi_Wait 
    Task1 : Boolean := False; 
    Task2 : Boolean := False; 
end Multi_Wait; 

Ensuite, votre code peut faire

select 
    Multi_Wait.Wait_For_Either (Task_1 => Task_1, Task_2 => Task_2); 

    if not Task_1 and Task_2 then 
     abort T1; 

     return False; 
    end if; 
or 
    delay 4.0; 
end select; 

Vos tâches appellent le procédure appropriée au lieu d'attendre un deuxième appel d'entrée.