Отмена процесса в Аде, который использует защищенный объект, который требует
У меня проблемы с моей программой.
У меня есть процесс, который вызывает функцию (Take_Job), которая должна оставаться заблокированной, пока не пройдет время (MINIMUM_WAIT). Если этого не произойдет, появится сообщение об этой ситуации.
for Printer_Id in Type_Printer_Id loop
select
delay MINIMUM_WAIT
Pragma_Assert (True, "");
then abort
Take_Job (Controller,
Printer_Id,
Max_Tonner,
Job,
Change_Tonner);
Pragma_Assert
(False,
"Testing of Take_Job hasn't been successful. It should have remained blocked.");
end select;
end loop;
Функция Take_Job вызывает запись в защищенном объекте:
procedure Take_Job (R : in out Controller_Type;
Printer : in Type_Printer_Id;
Siz : in Typo_Volume;
Job : out Typo_Job;
Excep_Tonner : out Boolean) is
begin
R.Take_Job(Printer, Siz, Job, Excep_Tonner);
end Take_Job;
Где "R" - защищенный объект.
Следующий код представляет собой запись защищенного объекта. На самом деле условие "когда" истинно, потому что мне нужно проверить кое-что с параметрами записи. Поскольку Ада не позволяет мне этого делать, я копирую параметры внутри защищенного объекта и вызываю "отложенную запись", а затем в "отложенной записи" я проверю, что условие выполнено, прежде чем продолжить.
entry Take_Job(Printer_Id: in Type_Printer_Id; Remaining: in Type_Volume; Job: out Type_Job; exceptionTonner: out Boolean)
when True is
begin
Copy_Remaining(Printer_Id) := Remaining;
requeue Take_Job_Delayed(Printer_Id);
end Take_Job;
Давайте посмотрим код "отложенной записи":
entry Take_Job_Delayed(for J in Type_Printer_Id)(Printer_Id: in Type_Printer_Id; Remaining: in Type_Volume; Job: out Type_Job; exceptionTonner: out Boolean)
when False is -- I've done this on purpose
begin
null; -- Actually, there would be a lot of code here
end Take_Job_Delayed;
Допустим, моя цель - передать MINIMUM_WAIT и запустить "Pragma_Assert(True, "")". Если я поставлю условие "когда" Take_Job в "False", то все будет работать нормально. Take_Job никогда не принимается, и Pragma_Assert будет выполнен. Если я установлю его в "True" и условие "когда" Take_Job_Delayed в "False", я не получу тот же эффект, и процесс будет заблокирован, и ни один из Pragma_Asserts не будет выполнен.
Зачем? Похоже, что проблема в "требовании" или где-то рядом, но почему это происходит?
1 ответ
Вы должны сделать заявку with abort
;
entry Take_Job(Printer_Id: in Type_Printer_Id;
Remaining: in Type_Volume;
Job: out Type_Job;
exceptionTonner: out Boolean)
when True is
begin
Copy_Remaining(Printer_Id) := Remaining;
requeue Take_Job_Delayed(Printer_Id) with abort;
end Take_Job;
потому что в противном случае возможность прервать входной вызов была потеряна. Подробности в ARM 9.5.4 и более понятное объяснение в Burns & Wellings "Параллельность в Аде".