Защищенные процедуры обработки прерываний
Ада предусматривает два стиля установки обработчиков прерываний: вложенный (nested) и не-вложенный (non-nested).
При вложенном стиле, обработчик прерываний в защищенном объекте устанавливается неявно в момент появления данного защищенного объекта, и после того как защищенный объект прекращает существовать, происходит неявное восстановление старого обработчика прерывания.
При не-вложенном стиле, обработчик прерываний устанавливается явным вызовом процедуры, и старый обработчик прерывания может быть восстановлен только явно.
Существует два способа определения устанавливаемого обработчика прерывания вложенного стиля, в зависимости от используемой в защищенном описании директивы компилятора.
В первом случае, устанавливаемый с использованием вложенного стиля обработчик прерывания, идентифицируется последующей директивой компилятора Attach_Handler, которая появляется в защищенном описании и имеет следующий вид:
pragma Attach_Handler (Handler, Interrupt); |
Здесь, Handler указывает имя защищенной процедуры без параметров, которая описана в защищенном описании, а Interrupt является выражением типа Interrupt_ID.
Защищенное описание должно выполняться на уровне библиотеки, то есть, оно не может быть вложено в тело подпрограммы, тело задачи или инструкцию блока.
Однако, если защищенное описание описывает защищенный тип, то индивидуальный защищенный объект этого типа может быть размещен в этих местах.
Динамическое размещение с помощью аллокатора new обладает большей гибкостью: аллокация защищенного объекта с обработчиком прерывания устанавливает обработчик прерывания, ассоциированный с этим защищенным объектом, а деаллокация защищенного объекта восстанавливает ранее установленный обработчик.
Выражение типа Interrupt_ID не обязано быть статическим.
В частности, его значение может зависить от дискриминанта защищенного типа. Например:
package Nested_Handler_Example is
protected type Device_Interface (Int_ID : Ada.Interrupts.Interrupt_ID) is procedure Handler; pragma Attach_Handler (Handler, Int_ID); end Nested_Handler_Example; |
Во втором случае, устанавливаемый с использованием вложенного стиля обработчик прерывания, идентифицируется последующей директивой компилятора Interrupt_Handler, которая появляется в защищенном описании и имеет следующий вид:
pragma Interrupt_Handler (Handler, Interrupt); |
Как и в случае использования директивы Attach_Handler, защищенное описание не может быть вложено в тело подпрограммы, тело задачи или инструкцию блока.
Кроме того, эта директива компилятора имеет одно дополнительное ограничение: если защищенная процедура описана для защищенного типа, то объекты этого типа также не могут быть расположены в этих местах.
Следовательно, они должны создаваться динамически, с помощью new.