Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Скачиваний:
76
Добавлен:
02.04.2015
Размер:
8.79 Mб
Скачать
      1. Пример – регистрация сообщений об ошибках

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

int input_proc(void *client_data, int rcvid, void *msg, size_t msglen) {

struct log_message *log = (struct log_message *)msg;

/* Обработка только регистрирующих (log) сообщений */

if (log->type == LOG_MSG) {

PtWidget_t *text = (PtWidget_t *)client_data;

struct log_message header;

int msg_offset = offsetof(struct log_message, msg);

int log_msglen;

int status;

/* Смотрим: если весь наш заголовок в буфере - это оно */

if (msglen < msg_offset) {

/* Читаем во всём заголовке */

if (MsgRead(rcvid, &header, msg_offset, 0) = = -1) {

status = errno;

MsgError( rcvid, status);

return Pt_HALT; /* отпускаем*/

}

log = &header;

}

log_msglen = msg_offset+log->msg_len;

/* Смотрим, всё ли сообщение в буфере */

if (msglen < log_msglen) {

struct log_message *log_msg = (struct log_message *)alloca(log_msglen);

/* Читаем остаток сообщения из пространства стека */

if (log_msg = = NULL || MsgRead( rcvid, log_msg, log_msglen, 0) = = -1) {

status = errno;

MsgError( rcvid, status);

return Pt_HALT; /* отпускаем */

}

log = log_msg;

}

add_msg(text, log);

status = 0;

MspReply( rcvid, 0, 0, 0);

}

return Pt_HALT;

}

Это приложение регистрирует функцию input_proc() как обработчик ввода для обработки не-Photon'овских сообщений от каких-либо других процессов. Функция input_proc() вначале проверяет тип пришедшего сообщения. Если обработчик ввода не является ответственным за этот тип сообщения, он немедленно возвращает управление. Это важно, поскольку будут вызваны также и какие-либо другие неспециализированные обработчики ввода, которые были зарегистрированы, и только один из них будет нести ответственность по данному сообщению. Если тип полученного сообщения – регистрирующее сообщение, функция убеждается, что Photon прочёл в свой буфер событий сообщение целиком. Это можно определить, проверив длину сообщения, представленную как msglen в обработчике ввода. Если часть сообщения в буфере событий отсутствует, в памяти выделяется буфер сообщения и вызывается функция MsgRead(), чтобы получить сообщение целиком. Затем функция input_proc() вызывает функцию add_msg(), чтобы добавить сообщение в текстовый виджет, и выдаёт ответ на сообщение.

Когда input_proc() завершает свою работу, она возвращает значение Pt_HALT. Это указывает Photon'овской библиотеке виджета не удалять обработчик ввода.

    1. ИмпульсыPhoton'а

[Прим. пер. Импульсы Photon'а – это отнюдь не импульсы QNX 6, а прокси QNX 4. Именно этот механизм.]

В дополнении к синхронному обмену сообщений, Photon поддерживает импульсы. Процесс, желающий уведомить другой процесс, но не желающий при этом ожидать ответа, может использовать импульсы Photon'а. Например, сервер может использовать импульс, чтобы общаться с клиентом в ситуации, когда отсылка сообщения может оставить их обоих SEND-блокированными (и поэтому попавшими в тупик). Импульс Photon'а определяется по его отрицательному идентификатору процесса, который может быть использован в качестве аргумента pid функции PtAppAddInput(). Этот идентификатор процесса является локальным для Вашего приложения. Если Вы хотите, чтобы другой процесс прислал Вам импульс, Вы должны "взвести" импульс, используя функцию PtPulseArm(). Это создаёт объект типа PtPulseMsg_t, который может быть послан другому процессу в сообщении. Другой процесс затем будет способен посылать импульсы, вызывая функцию MsgDeliverEvent().

 В OC QNX версии 6 тип PtPulseMsg_t является структурой sigevent. Биты в msg.sigev_value.sival_int, которые соответствуют _NOTIFY_COND_MASK, сброшены, но могут быть установлены приложением, отсылающим импульс. Более подробно см. в описании функции ionotify() "Справочника библиотечных функций QNX 6".

PtPulseArm() (описанная в "Справочнике библиотечных функций Photon'а ") просто берёт структуру sigevent. Функции PtPulseArmFd() и PtPulseArmPid() существуют для совместимости с более ранними версиями OC QNX и Photon microGUI.

Давайте посмотрим код, который Вам надо написать, чтобы поддерживать импульс в:

  • Приложении Photon'а, которое получает импульсы

  • Приложении Photon'а, которое выпускает импульсы

Соседние файлы в папке Литература_1