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

на главную - закладки

Жанры

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

Кёртен Роб

Шрифт:
Этап 4

Обработка команды «get» («получить») на этапе 4 во многом аналогична (по части приведения типов), кроме того, что на этот раз мы записываем данные в структуру вместо считывания из нее. Заметьте, что мы также присваиваем переменной nbytes число байт, которые мы хотим возвратить клиенту. В случае более сложного доступа к данным вы должны были бы возвратить размер области данных (т.е. если бы эта область была бы структурой, вам нужно было бы возвратить ее размер).

Этап 5

Наконец, для возврата данных клиенту мы должны вспомнить, что клиент ожидает не только возвращаемые данные (если таковые

имеются), но и заголовочную структуру, за которой идут эти данные. Поэтому на этом этапе мы обнуляем заголовочную структуру и устанавливаем число байт (поле nbytes) в число байт, которые мы намерены возвратить (вспомните, мы обнуляли это значение ранее). Затем мы создаем одноэлементный вектор ввода/ вывода с указателем на заголовок и расширяем размер заголовка на число возвращаемых байт. В конце мы просто сообщаем библиотеке администратора ресурсов, что мы возвращаем клиенту одноэлементный вектор ввода/вывода.

Важное замечание

Вспомните рассуждения про следующую за заголовком область данных из примера io_write, приведенного выше. Мы утверждали, что байты, расположенные сразу после заголовка, могут как быть полноценными, так и нет (то есть возможны случаи, когда область данных со стороны клиента была считана лишь частично) — в зависимости от того, сколько данных считала библиотека администратора ресурсов. Затем мы говорили о том, что было бы неэффективно пытаться «сэкономить» лишнюю операцию обмена сообщениями и «повторно использовать» область данных. Однако, в случае с devctl все обстоит несколько иначе, особенно если количество передаваемых данных достаточно невелико (как было и в наших примерах). Здесь у нас есть неплохой шанс того, что данные от клиента были-таки считаны в область данных целиком, и тогда повторное их считывание будет напрасной тратой сил. Узнать, сколько у вас доступно пространства, очень просто: поле size («размер») структуры ctp содержит число байт, доступных для вас, начиная с параметра msg. Размер доступной области данных, расположенной за буфером сообщений, вычисляется как разность между размером буфера сообщений и полем size структуры ctp:

data_area_size = ctp->size - sizeof(*msg);

Отметим, что этот размер будет действителен также и в случае возврата данных клиенту (как при команде DCMD_AUDIO_GET_SAMPLE_RATE).

Для всего, что превосходит по размеру выделенную область, вам придется получать данные от клиента так же, как мы это делали в примере с io_write (см. выше), а также выделить буфер для возврата данных клиенту.

Дополнительно

Теперь, после того как мы овладели «основами» построения администраторов ресурсов, пришло время рассмотреть более сложные вопросы. К ним относятся:

• расширение OCB;

• расширение атрибутной записи;

• блокирование в пределах администратора ресурсов;

• возврат элементов каталога.

Расширение OCB

В ряде случаев у вас может возникнуть необходимость расширения OCB. Процедура эта является относительно безболезненной. Обычно OCB расширяют дополнительными флагами, характеризующими каждый конкретный open. Один такой флаг можно было бы использовать с обработчиком io_unblock для кэширования значения флага ядра _NTO_MI_UNBLOCK_REQ (подробнее

см. параграф «Применение флага _NTO_MI_UNBLOCK_REQ» в главе «Обмен сообщениями»).

Для расширения блока OCB вам нужно будет обеспечить две дополнительных функции: одну для выделения OCB, и одну — для его освобождения. Затем вы должны будете привязать эти две функции к записи точки монтирования. (Да-да, совершенно верно — вам понадобится запись точки монтирования, даже если только для этого.) И наконец, вы должны будете определить ваш собственный тип OCB, чтобы все прототипы в программе были корректны.

Давайте рассмотрим сначала описание типа OCB, а затем уже поглядим, как переопределяются функции:

#define IOFUNC_OCB_T struct my_ocb

#include <sys/iofunc.h>

Это сообщает включаемому файлу

<sys/iofunc.h>
, что именованная константа IOFUNC_OCB_T теперь указывает на вашу новую усовершенствованную структуру OCB.

Очень важно
иметь в виду, что ваш «расширенный» OCB должен содержать «стандартный» OCB в качестве своего первого элемента! Это так, потому что вспомогательная библиотека POSIX везде передает указатель на то, что она считает стандартным OCB — о вашем расширенном OCB ей ничего не известно, так что первый элемент данных, расположенный по этому указателю, должен соответствовать стандартному OCB.

Вот наш расширенный OCB:

typedef struct my_ocb {

 iofunc_ocb_t normal_ocb;

 int my_extra_flags;

 ...

} my_ocb_t;

А вот код, иллюстрирующий, как переопределяются функции выделения и освобождения OCB в записи точки монтирования:

// Декларации

iofunc_mount_t mount;

iofunc_funcs_t mount_funcs;

// Задать в записи точки монтирования

// наши функции выделения/освобождения

// _IOFUNC_NFUNCS взята из .h-файла

mount_funcs.nfuncs = _IOFUNC_NFUNCS;

// Новая функция выделения OCB

mount_funcs.ocb_calloc = my_ocb_calloc;

// Новая функция освобождения OCB

mount_funcs.ocb_free = my_ocb_free;

// Настроить запись точки монтирования

memset(&mount, 0, sizeof(mount));

После этого остается только привязать запись точки монтирования к атрибутной записи:

...

attr.mount = &mount;

Функции my_ocb_calloc и my_ocb_free отвечают за выделение обнуленного расширенного OCB и освобождения OCB, соответственно. Вот их прототипы:

IOFUNC_OCB_T* my_ocb_calloc(resmgr_context_t *ctp,

Поделиться:
Популярные книги

Газлайтер. Том 10

Володин Григорий
10. История Телепата
Фантастика:
боевая фантастика
5.00
рейтинг книги
Газлайтер. Том 10

На границе империй. Том 7. Часть 2

INDIGO
8. Фортуна дама переменчивая
Фантастика:
космическая фантастика
попаданцы
6.13
рейтинг книги
На границе империй. Том 7. Часть 2

Звездная Кровь. Изгой

Елисеев Алексей Станиславович
1. Звездная Кровь. Изгой
Фантастика:
боевая фантастика
попаданцы
рпг
5.00
рейтинг книги
Звездная Кровь. Изгой

Хозяин Теней 4

Петров Максим Николаевич
4. Безбожник
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Хозяин Теней 4

Картофельное счастье попаданки

Иконникова Ольга
Фантастика:
фэнтези
5.00
рейтинг книги
Картофельное счастье попаданки

Экзорцист: Проклятый металл. Жнец. Мор. Осквернитель

Корнев Павел Николаевич
Фантастика:
фэнтези
героическая фантастика
5.50
рейтинг книги
Экзорцист: Проклятый металл. Жнец. Мор. Осквернитель

Доктора вызывали? или Трудовые будни попаданки

Марей Соня
Фантастика:
юмористическая фантастика
попаданцы
5.00
рейтинг книги
Доктора вызывали? или Трудовые будни попаданки

Метатель

Тарасов Ник
1. Метатель
Фантастика:
боевая фантастика
попаданцы
рпг
фэнтези
фантастика: прочее
постапокалипсис
5.00
рейтинг книги
Метатель

Моя на одну ночь

Тоцка Тала
Любовные романы:
современные любовные романы
короткие любовные романы
5.50
рейтинг книги
Моя на одну ночь

Чехов. Книга 2

Гоблин (MeXXanik)
2. Адвокат Чехов
Фантастика:
фэнтези
альтернативная история
аниме
5.00
рейтинг книги
Чехов. Книга 2

Хозяин Теней 2

Петров Максим Николаевич
2. Безбожник
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Хозяин Теней 2

Сумеречный стрелок 7

Карелин Сергей Витальевич
7. Сумеречный стрелок
Фантастика:
городское фэнтези
попаданцы
аниме
5.00
рейтинг книги
Сумеречный стрелок 7

Жизнь под чужим солнцем

Михалкова Елена Ивановна
Детективы:
прочие детективы
9.10
рейтинг книги
Жизнь под чужим солнцем

Красноармеец

Поселягин Владимир Геннадьевич
1. Красноармеец
Фантастика:
боевая фантастика
попаданцы
4.60
рейтинг книги
Красноармеец