Справочник по Ada 95
Подсистема связи между разделами E.5
Подсистема связи между разделами (PCS) предоставляет средства для поддержки связи между активными разделами распределённой программы. Пакет System.RPC является определяемым языком интерфейсом к PCS. Реализация, соответствующая данному приложению, должна использовать интерфейс RPC для реализации вызовов удалённых подпрограмм.
Статическая семантика
Существует следующий определяемый языком пакет библиотеки:
with Ada.Streams; -- см. 13.13.1
package System.RPC is
package System.RPC is
type Partition_ID is range 0 .. определяемое реализацией;
Communication_Error : exception;
type Params_Stream_Type (
Initial_Size : Ada.Streams.Stream_Element_Count) is new
Ada.Streams.Root_Stream_Type with private;
Initial_Size : Ada.Streams.Stream_Element_Count) is new
Ada.Streams.Root_Stream_Type with private;
procedure Read(
Stream : in out Params_Stream_Type;
Item : out Ada.Streams.Stream_Element_Array;
Last : out Ada.Streams.Stream_Element_Offset);
Stream : in out Params_Stream_Type;
Item : out Ada.Streams.Stream_Element_Array;
Last : out Ada.Streams.Stream_Element_Offset);
procedure Write(
Stream : in out Params_Stream_Type;
Item : in Ada.Streams.Stream_Element_Array);
Stream : in out Params_Stream_Type;
Item : in Ada.Streams.Stream_Element_Array);
-- Синхронный вызов
procedure Do_RPC(
Partition : in Partition_ID;
Params : access Params_Stream_Type;
Result : access Params_Stream_Type);
procedure Do_RPC(
Partition : in Partition_ID;
Params : access Params_Stream_Type;
Result : access Params_Stream_Type);
-- Асинхронный вызов
procedure Do_APC(
Partition : in Partition_ID;
Params : access Params_Stream_Type);
procedure Do_APC(
Partition : in Partition_ID;
Params : access Params_Stream_Type);
-- Обработчик входящих RPC
type RPC_Receiver is access procedure(
Params : access Params_Stream_Type;
Result : access Params_Stream_Type);
type RPC_Receiver is access procedure(
Params : access Params_Stream_Type;
Result : access Params_Stream_Type);
procedure Establish_RPC_Receiver(
Partition : in Partition_ID;
Receiver : in RPC_Receiver);
Partition : in Partition_ID;
Receiver : in RPC_Receiver);
private
... -- не определено языком
end System.RPC;
... -- не определено языком
end System.RPC;
Значение типа Partition_ID используется для идентификации раздела.
Объект типа Params_Stream_Type используется для идентификации конкретной удалённой подпрограммы, которая вызывается, а также для маршалинга и унмаршалинга параметров или результата вызова удалённой подпрограммы в процессе их передачи между разделами.
Процедуры Read и Write переопределяют соответствующие абстрактные операции для типа Params_Stream_Type.
Динамическая семантика
Процедуры Do_RPC и Do_APC отправляют сообщение активному разделу, идентифицируемому параметром Partition.
После отправки сообщения Do_RPC блокирует вызывающую задачу до тех пор, пока не придёт ответное сообщение от вызываемого раздела или пока не будет обнаружена ошибка в подсистеме связи, в этом случае Communication_Error поднимается в момент вызова Do_RPC.
Do_APC работает так же, как Do_RPC, за исключением того, что она может вернуть сразу после отправки сообщения.
При нормальном возврате поток, обозначенный параметром Result в Do_RPC, содержит ответное сообщение.
Процедура System.RPC.Establish_RPC_Receiver вызывается один раз сразу после разработки библиотек активного раздела (то есть сразу после разработки раздела), если раздел включает библиотеку RCI, но до вызова основной подпрограммы (если таковая имеется). Параметр Partition — это Partition_ID активного разрабатываемого раздела. Параметр Receiver обозначает предоставляемую реализацией процедуру, называемую приёмником RPC, которая будет обрабатывать все RPC, полученные разделом от PCS. Establish_RPC_Receiver сохраняет ссылку на приёмник RPC; когда сообщение принимается вызываемым разделом, приёмник RPC вызывается со потоком Params, содержащим сообщение. Когда приёмник RPC возвращается, содержимое потока, обозначенного Result, помещается в сообщение и отправляется обратно вызывающему разделу.
Если вызов Do_RPC прерван, отправляется сообщение об отмене вызываемому разделу, чтобы запросить прерывание выполнения удалённо вызываемой подпрограммы.
Подпрограммы, объявленные в System.RPC, являются потенциально блокирующими операциями.
Требования к реализации
Реализация приёмника RPC должна быть рекурсивной, что позволяет параллельным вызовам его со стороны PCS обслуживать параллельные вызовы удалённых подпрограмм в раздел.
Реализация не должна ограничивать замену тела System.RPC. Реализация не должна ограничивать дочерние элементы System.RPC. Соответствующие разрешения на реализацию в начале Приложения А не применяются.
Если реализация System.RPC предоставлена пользователем, реализация должна поддерживать вызовы удалённых подпрограмм, как указано.
Требования к документации
Реализация PCS должна документировать, вызывается ли приёмник RPC из параллельных задач. Если существует верхний предел для количества таких задач, этот предел также должен быть задокументирован вместе с механизмами его настройки (если это поддерживается).
Разрешения на реализацию
PCS разрешено содержать определяемые реализацией интерфейсы для явного обмена сообщениями, широковещательной рассылки и т. д. Аналогично, разрешено предоставлять дополнительные интерфейсы для запроса состояния удалённого раздела (учитывая его идентификатор раздела) или самого PCS, для установки тайм-аутов и параметров повторных попыток, для получения более подробных статусов ошибок и т. д. Эти дополнительные интерфейсы должны предоставляться в дочерних пакетах System.RPC.
Тело пакета System.RPC не обязательно должно предоставляться реализацией.
Рекомендации по реализации
По возможности, PCS на вызываемом разделе должен позволять нескольким задачам вызывать приёмник RPC с различными сообщениями и должен позволять им блокироваться до возврата соответствующего тела подпрограммы.
Операция Write над потоком типа Params_Stream_Type должна поднимать Storage_Error, если она исчерпывает место, пытаясь записать Item в поток.
ПРИМЕЧАНИЯ
8 Пакет System.RPC не предназначен для прямого вызова пользовательскими программами. Вместо этого он предназначен для использования в реализации вызовов удалённых подпрограмм, вызываемых вызывающими заглушками, сгенерированными для библиотеки интерфейса удалённого вызова, для инициирования удалённого вызова, и в свою очередь, вызывающих обратно приёмник RPC, который отправляет сообщения в заглушки получателя, сгенерированные для тела интерфейса удалённого вызова, чтобы обработать удалённый вызов, полученный от другого места.