Справочник Ada 95
9.4 Защищённые блоки и защищённые объекты
Защищённый объект обеспечивает координированный доступ к общим данным через вызовы видимых защищённых операций, которые могут быть защищёнными подпрограммами или защищёнными входами. Защищённый блок объявляется с помощью объявления защищённого блока, которое имеет соответствующее protected_body. Объявление защищённого блока может быть protected_type_declaration, в этом случае оно объявляет именованный защищённый тип; в качестве альтернативы, оно может быть single_protected_declaration, в этом случае оно определяет анонимный защищённый тип, а также объявляет именованный защищённый объект этого типа.
Синтаксис
protected_type_declaration ::=
protected type defining_identifier [known_discriminant_part] is protected_definition;
protected type defining_identifier [known_discriminant_part] is protected_definition;
single_protected_declaration ::=
protected defining_identifier is protected_definition;
protected defining_identifier is protected_definition;
protected_definition ::=
{ protected_operation_declaration }
[ private
{ protected_element_declaration } ]
end [protected_identifier]
{ protected_operation_declaration }
[ private
{ protected_element_declaration } ]
end [protected_identifier]
protected_operation_declaration ::= subprogram_declaration
| entry_declaration
| aspect_clause
| entry_declaration
| aspect_clause
protected_element_declaration ::= protected_operation_declaration
| component_declaration
| component_declaration
protected_body ::=
protected body defining_identifier is
{ protected_operation_item }
end [protected_identifier];
protected body defining_identifier is
{ protected_operation_item }
end [protected_identifier];
protected_operation_item ::= subprogram_declaration
| subprogram_body
| entry_body
| aspect_clause
| subprogram_body
| entry_body
| aspect_clause
Если protected_identifier появляется в конце protected_definition или protected_body, то оно должно повторять defining_identifier.
Правила легальности
Объявление защищённого блока требует завершения, которое должно быть protected_body, и каждый protected_body должен быть завершением какого-либо объявления защищённого блока.
Статическая семантика
protected_definition определяет защищённый тип и его первый подтип. Список protected_operation_declaration в protected_definition, вместе с known_discriminant_part, если таковой имеется, называется видимой частью защищённого блока. Необязательный список protected_element_declaration после ключевого слова private называется приватной частью защищённого блока.
Динамическая семантика
Выполнение объявления защищённого блока выполняет protected_definition. Выполнение single_protected_declaration также создаёт объект (анонимного) защищённого типа.
Выполнение protected_definition создаёт защищённый тип и его первый подтип; оно также включает выполнение component_declaration и protected_operation_declaration в заданном порядке.
В рамках инициализации защищённого объекта выполняются любые ограничения, относящиеся к объекту (см. 3.8).
Выполнение protected_body не имеет другого эффекта, кроме как установить, что защищённые операции типа могут отныне вызываться без сбойного выполнения Elaboration_Check.
Содержимое объекта данного защищённого типа включает:
- Значения компонентов защищённого объекта, включая (неявным образом) очередь ввода/вывода для каждого входа, объявленного для защищённого объекта;
- Представление состояния ресурса выполнения, ассоциированного с защищённым объектом (такой ресурс ассоциирован с каждым защищённым объектом).
Для чтения или обновления любых компонентов защищённого объекта необходимо получить доступ к ресурсу выполнения, ассоциированному с защищённым объектом; он может быть получен (как часть защищённого действия — см. 9.5.1) либо для одновременного чтения без изменения, либо для эксклюзивного чтения и записи.
Первым шагом завершения работы защищённого объекта является удаление каждого оставшегося вызова из очереди ввода/вывода объекта и поднятие Program_Error в месте соответствующего entry_call_statement.
ПРИМЕЧАНИЯ
13 Внутри объявления или тела защищённого блока имя защищённого блока обозначает текущую экземпляцию блока (см. 8.6), а не первый подтип соответствующего защищённого типа (и, следовательно, имя не может быть использовано как subtype_mark).
14 selected_component может использоваться для обозначения дискриминанта защищённого объекта (см. 4.1.3). Внутри защищённого блока имя дискриминанта защищённого типа обозначает соответствующий дискриминант текущей экземпляции блока.
15 Защищённый тип является ограниченным типом (см. 7.5), и, следовательно, не имеет ни операции присваивания, ни предопределённых операторов равенства.
16 Тела защищённых операций, указанные в protected_body, определяют действия, которые выполняются при вызовах защищённых операций.
17 Объявления в приватной части видны только внутри приватной части и тела защищённого блока.
Примеры
Пример объявления защищённого типа и соответствующего тела:
protected type Resource is
entry Seize;
procedure Release;
private
Busy : Boolean := False;
end Resource;
entry Seize;
procedure Release;
private
Busy : Boolean := False;
end Resource;
protected body Resource is
entry Seize when not Busy is
begin
Busy := True;
end Seize;
entry Seize when not Busy is
begin
Busy := True;
end Seize;
procedure Release is
begin
Busy := False;
end Release;
end Resource;
begin
Busy := False;
end Release;
end Resource;
Пример одиночного объявления защищённого блока и соответствующего тела:
protected Shared_Array is
-- Index, Item, and Item_Array are global types
function Component (N : in Index) return Item;
procedure Set_Component(N : in Index; E : in Item);
private
Table : Item_Array(Index) := (others => Null_Item);
end Shared_Array;
-- Index, Item, and Item_Array are global types
function Component (N : in Index) return Item;
procedure Set_Component(N : in Index; E : in Item);
private
Table : Item_Array(Index) := (others => Null_Item);
end Shared_Array;
protected body Shared_Array is
function Component(N : in Index) return Item is
begin
return Table(N);
end Component;
function Component(N : in Index) return Item is
begin
return Table(N);
end Component;
procedure Set_Component(N : in Index; E : in Item) is
begin
Table(N) := E;
end Set_Component;
end Shared_Array;
begin
Table(N) := E;
end Set_Component;
end Shared_Array;
Примеры защищённых объектов:
Control : Resource;
Flags : array(1 .. 100) of Resource;
Flags : array(1 .. 100) of Resource;