KasperskyOS API >
Библиотека libkos > Инициализация IPC-транспорта для межпроцессного взаимодействия и управление обработкой IPC-запросов (transport-kos.h, transport-kos-dispatch.h)
Инициализация IPC-транспорта для межпроцессного взаимодействия и управление обработкой IPC-запросов (transport-kos.h, transport-kos-dispatch.h)
API определены в заголовочных файлах transport-kos.h
и transport-kos-dispatch.h
из состава KasperskyOS SDK, которые расположены по пути sysroot-*-kos/include/coresrv/nk
.
Возможности API:
Сведения о функциях API приведены в таблицах ниже.
В этом разделе приведены примеры использования API. В этих примерах программы, которые являются серверами, имеют следующую формальную спецификацию:
FsDriver.edl
entity FsDriver
components {
operationsComp : Operations
}
Operations.cdl
component Operations
endpoints {
fileOperations : FileIface
}
FileIface.idl
package FileIface
interface {
Open(in array<UInt8, 1024> path);
Read(out sequence<UInt8, 2048> content);
}
Инициализация IPC-транспорта для межпроцессного взаимодействия
Чтобы инициализировать IPC-транспорт для взаимодействия с другими процессами, нужно вызвать функцию NkKosTransport_Init()
или NkKosTransportSync_Init()
, объявленные в заголовочном файле transport-kos.h
.
Пример использования функции NkKosTransport_Init()
на стороне клиента:
int main(int argc, const char *argv[])
{
NkKosTransport driver_transport;
struct FileIface_proxy file_operations_proxy;
struct FileIface_Open_req req;
struct FileIface_Open_res res;
Handle driver_handle;
rtl_uint32_t file_operations_riid;
if (KnCmConnect("FsDriver", "operationsComp.fileOperations", INFINITE_TIMEOUT,
&driver_handle, &file_operations_riid) == rcOk) {
NkKosTransport_Init(&driver_transport, driver_handle, NK_NULL, 0);
FileIface_proxy_init(&file_operations_proxy, &driver_transport.base,
(nk_iid_t) file_operations_riid);
}
...
strncpy(req.path, "/example/file/path", sizeof(req.path));
if (FileIface_Open(file_operations_proxy.base, &req, NULL,
&res, NULL) != NK_EOK) {
...
}
...
}
Если клиенту требуется использовать несколько служб, то нужно инициализировать столько же прокси-объектов. При инициализации каждого прокси-объекта нужно указать IPC-транспорт, ассоциированный через клиентский IPC-дескриптор с нужным сервером. При инициализации нескольких прокси-объектов, относящихся к службам одного сервера, можно указать один и тот же IPC-транспорт, который ассоциирован с этим сервером.
Пример использования функции NkKosTransport_Init()
на стороне сервера:
int main(int argc, const char *argv[])
{
...
NkKosTransport transport;
Handle handle;
char client[32];
char endpoint[32];
Retcode rc = KnCmListen(RTL_NULL, INFINITE_TIMEOUT, client, endpoint);
if (rc == rcOk)
rc = KnCmAccept(client, endpoint,
FsDriver_operationsComp_fileOperations_iid,
INVALID_HANDLE, &handle);
...
NkKosTransport_Init(&transport, handle, NK_NULL, 0);
...
do
{
...
rc = nk_transport_recv(&transport.base, ...);
if (rc == NK_EOK) {
rc = FsDriver_entity_dispatch(...);
if (rc == NK_EOK) {
rc = nk_transport_reply(&transport.base, ...);
}
}
}
while (rc == NK_EOK)
return EXIT_SUCCESS;
}
Если сервер обрабатывает IPC-запросы, поступающие через несколько IPC-каналов, то нужно учитывать следующие особенности:
- Если слушающий дескриптор ассоциирован со всеми IPC-каналами, то для IPC-взаимодействия со всеми клиентами можно использовать один IPC-транспорт, ассоциированный с этим слушающим дескриптором.
- Если IPC-каналы ассоциированы с разными слушающими дескрипторами, то для IPC-взаимодействия с каждой группой клиентов, соответствующих одному слушающему дескриптору, нужно использовать отдельный IPC-транспорт, ассоциированный с этим слушающим дескриптором. При этом обработку IPC-запросов можно выполнять в параллельных потоках исполнения, если реализация методов служб потокобезопасна.
Функция NkKosTransportSync_Init()
позволяет инициализировать IPC-транспорт с поддержкой прерывания блокирующих системных вызовов Call()
и Recv()
. (Прерывание этих вызовов может потребоваться, например, чтобы корректно завершить процесс, который их выполняет.) Чтобы прерывать системные вызовы Call()
и Recv()
, нужно использовать API ipc_api.h.
Функция NkKosSetTransportTimeouts()
, объявленная в заголовочном файле transport-kos.h
, позволяет задать для IPC-транспорта максимальное время блокировки системных вызовов Call()
и Recv()
.
Запуск цикла обработки IPC-запросов
Цикл обработки IPC-запроса на сервере включает следующие стадии:
- Получение IPC-запроса.
- Обработка IPC-запроса.
- Отправка IPC-ответа.
Каждую стадию этого цикла можно выполнять отдельно, последовательно вызывая функции nk_transport_recv()
, диспетчер, nk_transport_reply()
. (Функции nk_transport_recv()
и nk_transport_reply()
объявлены в заголовочном файле sysroot-*-kos/include/nk/transport.h
из состава KasperskyOS SDK.) А можно вызвать функцию NkKosTransport_Dispatch()
или NkKosDoDispatch()
, внутри которых этот цикл выполняется полностью. (Функции NkKosTransport_Dispatch()
и NkKosDoDispatch()
объявлены в заголовочных файлах transport-kos.h
и transport-kos-dispatch.h
соответственно.) Использовать функцию NkKosDoDispatch()
удобнее, поскольку нужно выполнять меньше подготовительных операций (в том числе не требуется инициализировать IPC-транспорт).
Для инициализации структуры, передаваемой функции NkKosDoDispatch()
через параметр info
, можно использовать макросы, определенные в заголовочном файле transport-kos-dispatch.h
.
Функции NkKosTransport_Dispatch()
и NkKosDoDispatch()
можно вызывать из параллельных потоков исполнения, если реализация методов служб потокобезопасна.
Пример использования функции NkKosDoDispatch()
:
static nk_err_t Open_impl(...)
{
...
}
static nk_err_t Read_impl(...)
{
...
}
static struct FileIface *CreateFileOperations()
{
static const struct FileIface_ops ops = {
.Open = Open_impl,
.Read = Read_impl
};
static struct FileIface impl = {
.ops = &ops
};
return &impl;
}
int main(int argc, const char *argv[])
{
...
NkKosDispatchInfo info;
struct Operations_component component;
struct FsDriver_entity entity;
Handle handle = ServiceLocatorRegister("driver_connection", NULL, 0, &iid);
assert(handle != INVALID_HANDLE);
Operations_component_init(&component, CreateFileOperations());
FsDriver_entity_init(&entity, &component);
info = NK_TASK_DISPATCH_INFO_INITIALIZER(FsDriver, entity);
NkKosDoDispatch(handle, info);
return EXIT_SUCCESS;
}
Пример использования функции NkKosTransport_Dispatch()
:
static nk_err_t Open_impl(...)
{
...
}
static nk_err_t Read_impl(...)
{
...
}
static struct FileIface *CreateFileOperations()
{
static const struct FileIface_ops ops = {
.Open = Open_impl,
.Read = Read_impl
};
static struct FileIface impl = {
.ops = &ops
};
return &impl;
}
int main(int argc, const char *argv[])
{
...
NkKosTransport transport;
struct Operations_component component;
struct FsDriver_entity entity;
union FsDriver_entity_req req;
union FsDriver_entity_res res;
char res_buffer[FsDriver_entity_res_arena_size];
struct nk_arena res_arena = NK_ARENA_INITIALIZER(res_buffer,
res_buffer + sizeof(res_buffer));
Handle handle = ServiceLocatorRegister("driver_connection", NULL, 0, &iid);
assert(handle != INVALID_HANDLE);
NkKosTransport_Init(&transport, handle, NK_NULL, 0);
Operations_component_init(&component, CreateFileOperations());
FsDriver_entity_init(&entity, &component);
NkKosTransport_Dispatch(&transport.base, FsDriver_entity_dispatch,
&entity, &req, sizeof(FsDriver_entity_req),
RTL_NULL, &res, &res_arena);
return EXIT_SUCCESS;
}
Копирование данных в арену IPC-сообщений
Чтобы скопировать строку в арену IPC-сообщений, нужно вызвать функцию NkKosCopyStringToArena()
, объявленную в заголовочном файле transport-kos.h
. Эта функция резервирует участок арены и копирует строку в этот участок.
Пример использования функции NkKosCopyStringToArena()
:
static nk_err_t Read_impl(struct FileIface *self,
const struct FileIface_Read_req *req,
const struct nk_arena* req_arena,
struct FileIface_Read_res* res,
struct nk_arena* res_arena)
{
if (NkKosCopyStringToArena(&res_arena, &res.content,
"CONTENT OF THE FILE") != rcOk) {
...
}
return NK_EOK;
}
Сведения о функциях API
Функции transport-kos.h
Функция
|
Сведения о функции
|
NkKosTransport_Init()
|
Назначение
Инициализирует IPC-транспорт.
Параметры
- [out]
transport – указатель на структуру с параметрами IPC-транспорта. - [in]
handle – клиентский или серверный IPC-дескриптор. - [in]
view – параметр, который должен иметь значение NK_NULL . - [in]
size – параметр, который должен иметь значение 0 .
Возвращаемые значения
Нет.
|
NkKosTransportSync_Init()
|
Назначение
Инициализирует IPC-транспорт с поддержкой прерывания системных вызовов Call() и/или Recv() .
Параметры
- [out]
transport – указатель на структуру с параметрами IPC-транспорта. - [in]
handle – клиентский или серверный IPC-дескриптор. - [in,optional]
callSyncHandle – дескриптор объекта синхронизации IPC для системных вызовов Call() или INVALID_HANDLE , если прерывание системных вызовов Call() не требуется. - [in,optional]
recvSyncHandle – дескриптор объекта синхронизации IPC для системных вызовов Recv() или INVALID_HANDLE , если прерывание системных вызовов Recv() не требуется.
Возвращаемые значения
Нет.
|
NkKosSetTransportTimeouts()
|
Назначение
Задает для IPC-транспорта максимальное время блокировки системных вызовов Call() и Recv() .
Параметры
- [out]
transport – указатель на структуру с параметрами IPC-транспорта. - [in]
recvTimeout – максимальное время блокировки системных вызовов Recv() в миллисекундах или INFINITE_TIMEOUT , чтобы задать неограниченное время блокировки. - [in]
callTimeout – максимальное время блокировки системных вызовов Call() в миллисекундах или INFINITE_TIMEOUT , чтобы задать неограниченное время блокировки.
Возвращаемые значения
Нет.
|
NkKosTransport_Dispatch()
|
Назначение
Запускает цикл обработки IPC-запросов.
Параметры
- [in]
transport – указатель на поле base структуры с параметрами IPC-транспорта. - [in]
dispatch – указатель на диспетчер (dispatch-метод) из транспортного кода. Диспетчер имеет имя <имя класса процессов>_entity_dispatch . - [in]
impl – указатель на стаб, который представляет собой структуру с типом <имя класса процессов>_entity из транспортного кода. Через эту структуру диспетчер получает указатели на функции, реализующие методы служб. - [out]
req – указатель на объединение с типом <имя класса процессов>_entity_req из транспортного кода. Это объединение предназначено для сохранения фиксированной части IPC-запросов для любых методов служб, предоставляемых сервером. - [in]
req_size – максимальный размер фиксированной части IPC-запросов в байтах. Определяется как sizeof(<имя класса процессов>_entity_req) , где <имя класса процессов>_entity_req является типом из транспортного кода. - [in,out,optional]
req_arena – указатель на дескриптор арены IPC-запросов или RTL_NULL , если арена IPC-запросов не используется. Тип дескриптора определен в заголовочном файле sysroot-*-kos/include/nk/arena.h из состава KasperskyOS SDK. - [out]
res – указатель на объединение с типом <имя класса процессов>_entity_res из транспортного кода. Это объединение предназначено для сохранения фиксированной части IPC-ответов для любых методов служб, предоставляемых сервером. - [in,out,optional]
res_arena – указатель на дескриптор арены IPC-ответов или RTL_NULL , если арена IPC-ответов не используется. Тип дескриптора определен в заголовочном файле sysroot-*-kos/include/nk/arena.h из состава KasperskyOS SDK.
Возвращаемые значения
В случае неуспеха возвращает код ошибки.
|
NkKosCopyStringToArena()
|
Назначение
Резервирует участок арены и копирует строку в этот участок.
Параметры
- [in,out]
arena – указатель на дескриптор арены. Тип дескриптора определен в заголовочном файле sysroot-*-kos/include/nk/arena.h из состава KasperskyOS SDK. - [out]
field – указатель на дескриптор участка арены, куда скопирована строка. Тип дескриптора определен в заголовочном файле sysroot-*-kos/include/nk/types.h . - [in]
src – указатель на строку для копирования в арену IPC-сообщений.
Возвращаемые значения
В случае успеха возвращает rcOk , иначе возвращает код ошибки.
|
Функции transport-kos-dispatch.h
Функция
|
Сведения о функции
|
NkKosDoDispatch()
|
Назначение
Запускает цикл обработки IPC-запросов.
Параметры
- [in]
h – серверный IPC-дескриптор. - [in]
info – указатель на структуру, содержащую данные, которые требуются функции для использования транспортного кода (включая имена типов, размеры фиксированной части и арены IPC-сообщений).
Возвращаемые значения
Нет.
|
Идентификатор статьи: libkos_ipc_transport_api, Последнее изменение: 21 мая 2024 г.