Чтение онлайн

ЖАНРЫ

Введение в QNX/Neutrino 2. Руководство по программированию приложений реального времени в QNX Realtime Platform

Кёртен Роб

Шрифт:

}

Это очень удобно, поскольку позволяет вам помещать точки останова на принимающей функции и перехватывать сообщения (например, с помощью отладчика) в процессе работы.

Библиотека осуществляет все магические манипуляции внутри функции resmgr_handler, потому что это как раз то самое место, где сообщение анализируется и обрабатывается в соответствии с таблицами функций установления соединения и ввода/вывода, о которых мы уже говорили ранее.

В действительности, библиотека состоит из двух взаимодействующих уровней — базового, который обеспечивает «сырую» функциональность администратора ресурсов, и уровня POSIX, который содержит вспомогательные

функции POSIX и обработчики по умолчанию. Сейчас мы кратко обрисуем эти два уровня, а затем в разделе «Структура администратора ресурсов» рассмотрим все в подробностях.

Базовый уровень

Самый нижний, базовый, уровень состоит из функций, имена которых начинаются с «resmgr_». Этот класс функций относится к низкоуровневым механизмам функционирования администратора ресурсов.

Здесь я только кратко приведу описание этих функций, которые являются доступными и которые мы будем использовать. Затем я отправлю вас к изучению QSSL документации для получения более подробных сведений об этих функциях.

К функциям базового уровня относятся:

resmgr_msgreadv и resmgr_msgread

Считывают данных из адресного пространства клиента при помощи обмена сообщениями.

resmgr_msgwritev и resmgr_msgwrite

Записывают данные в адресное пространство клиента при помощи обмена сообщениями.

resmgr_open_bind

Связывает контекст с запросом на установление соединения, поступившим от соответствующей клиентской функции. Этот контекст далее будет использоваться функциями ввода/вывода.

resmgr_attach

Создает канал и связывает воедино имя пути, дескриптор диспетчера, функции установления соединения, функции ввода/вывода и другие параметры. Посылает сообщение администратору процессов для регистрации имени пути (префикса).

resmgr_detach

Противоположна функции resmgr_attach. Уничтожает связь между именем пути и администратором ресурса.

pulse_attach

Связывает код импульса с функцией. Поскольку приема сообщений реализуется библиотекой, это удобный способ «перехватывать управление» для обработки импульсов.

pulse_detach

Отвязывает код импульса от функции.

В дополнение к функциям, перечисленным выше, есть также множество функций, посвященных интерфейсу диспетчеризации.

Одна функция из вышеупомянутого списка заслуживает особого упоминания — функция resmgr_open_bind. Данная функция, когда приходит сообщение установления соединения (обычно это происходит в результате клиентского вызова open или fopen), создает некую контекстную информацию, чтобы она была готов к моменту прихода сообщения ввода/вывода. Почему ее не быт администраторе

/dev/null
? Потому что POSIX-функции обработки сообщений, принятые по умолчанию, сами вызывают для нас эту функцию. Если бы мы обрабатывали все сообщения самостоятельно, нам, конечно, пришлось бы вызвать данную функцию.

Функция resmgr_open_bind не только формирует контекстный блок для последующих сообщений ввода/вывода, но также инициализирует и другие структуры данных, используемые непосредственно библиотекой администратора ресурсов.

Остальные функции из вышеупомянутого списка достаточно интуитивны, так что отложим их обсуждение до тех пор, пока не дойдем до их явного применения.

Уровень POSIX

Второй

уровень библиотеки администратора ресурсов является POSIX-уровнем. Как и в случае с базовым уровнем, вы могли бы написать администратор ресурсов и без использования этих функций, но это отняло бы уйму трудов! Прежде чем обсуждать функции уровня POSIX в подробностях, мы должны рассмотреть ряд структур данных базового уровня, приходящие от клиентуры сообщения, а также общую структуру и сферу ответственности администратора ресурсов.

Написание администратора ресурсов

Теперь, когда мы знаем основы, — как выглядит мир глазами клиента, в каком цвете видит все администратор ресурсов, и что из себя представляют оба уровня библиотеки — пришло время сконцентрироваться на деталях.

В этом разделе мы рассмотрим следующие темы:

• структуры данных;

• структуру администратора ресурсов;

• структуры данных POSIX-уровня;

• подпрограммы обработки сообщений;

• и, конечно, множество примеров.

Постарайтесь запомнить приведенную ниже «большую картинку» — на ней изображено практически все, что имеет отношение к администратору ресурсов:

Архитектура администратора ресурсов — общая схема.

Структуры данных

Первое, в чем следует разобраться, — это структуры данных, которые управляют работой библиотеки:

• управляющая структура

resmgr_attr_t

• таблица функций установления соединения

resmgr_connect_funcs_t

• таблица функций ввода-вывода

resmgr_io_funcs_t
и еще одна внутренняя структура данных библиотеки:

• внутренний блок контекста

resmgr_context_t

Позже мы рассмотрим такие типы данных как блок открытого контекста (OCB), атрибутную запись (attributes structure) и запись точки монтирования (mount structure), которые используются POSIX-уровнем библиотеки.

Управляющая структура
resmgr_attr_t

Управляющая структура (типа

resmgr_attr_t
) передается функции resmgr_start, которая несколько ее элементов и отвечает за основной цикл приема сообщений.

Управляющая структура (взято из

<sys/dispatch.h>
) содержит следующее:

typedef struct _resmgr_attr {

 unsigned flags;

 unsigned nparts_max;

 unsigned msg_max_size;

 int (*other_func)(resmgr_context_t *ctp, void *msg);

} resmgr_attr_t;

Обработчик сообщений
other_func

Вообще говоря, использования этого элемента следует избегать. Этот элемент, если не равен NULL, указывает на подпрограмму, которая должна быть вызвана, если принято сообщение, не распознанное библиотекой. Хоть это и можно было бы использовать для реализации «нестандартных» сообщений, но это нехорошая практика (применяйте либо обработчики _IO_DEVCTL, либо _IO_MSG — см. ниже). Если вы хотите обрабатывать входящие импульсы, рекомендую для этого применять функцию pulse_attach.

Поделиться с друзьями: