MsgSend(), MsgSend_r()

Отправить сообщение

Прототип:

#include <sys/neutrino.h>
int MsgSend( int coid,
const void *smsg,
int sbytes,
void *rmsg,
int rbytes );
int MsgSend_r( int coid,
const void *smsg,
int sbytes,
void *rmsg,
int rbytes );

Аргументы:

coid
Идентификатор соединения, установленного для отправки сообщений с каналом сервера с помощью функции ConnectAttach() или name_open().
smsg
Указатель на буфер, содержащий отправляемое сообщение.
sbytes
Размер отправляемого сообщения в байтах.
rmsg
Указатель на буфер для приёма ответного сообщения от сервера.
rbytes
Размер буфера для ответного сообщения в байтах.

Библиотека:

libc

Описание:

Функции MsgSend() и MsgSend_r() отправляют сообщение в канал, идентифицируемый соединением coid.

Данные функции идентичны за исключением способа возврата ошибок.

Количество реально передаваемых байт имеет значение меньшее из заданных и отправителем, и получателем. Передаваемые данные не могут переполнять приёмный буфер, предоставленный получателем.

Поток-отправитель становится заблокированным, пока не получит ответ от получателя. Если поток-получатель находится в состоянии RECEIVE-блокировки на канале, то передача данных в его адресное пространство происходит немедленно, поток-получатель разблокируется и становится готов к выполнению. При этом поток-отправитель становится REPLY-блокированным. В случае, если нет потоков, ожидающих сообщения на канале, поток-отправитель становится SEND-блокированным и помещается в очередь (возможно, с другими потоками). В этом случае реальной передачи данных не происходит, пока принимающий поток не вызовет функцию MsgReceive*(). В этот момент поток-отправитель станет REPLY-блокированным.


Note: Эффективный приоритет потока-получателя может измениться (в значение приоритета потока-отправителя) при отправке ему сообщения. Наследование приоритетов является поведением по умолчанию и может быть изменено с помощью соответствующего флага при вызове функции создания канала.

MsgSendsv() является точкой завершения потока для функции ThreadCancel(); MsgSendsvnc() точкой завершения потока не является.

Состояния блокировки:

STATE_SEND
Сообщение было отправлено, но не получено. Если какой-либо поток ждет сообщений на канале, то это состояние пропускается и поток-отправитель сразу переходит в состояние STATE_REPLY.
STATE_REPLY
Сообщение было получено, но ещё не получен ответ. Отправитель переходит в это состояние сразу или из состояния STATE_SEND.

Сетевые взаимодействия

При отправке сообщения уделённому серверу (получателю) микроядро сначала передаёт его локальному сетевому менеджеру lsm-qnet.so. Локальный сетевой менеджер взаимодействует с удалённым сетевым менеджером, в результате чего происходит доставка сообщения потоку-серверу.

Передача сообщения от удалённого сетевого менеджера на сервер осуществляется с помощью специальной неблокирующей передачи сообщений. Поэтому на скорость передачи сообщения по сети влияет только скорость передачи данных через канал связи и затраты на функционирование менеджера протокола lsm-qnet.so, используемого модулем io-pkt-*.

Клиент остаётся заблокированным при вызове MsgSend() до тех пор пока не будет разблокирован сигналом, тайм-аутом ядра или при завершении функции.

Возвращаемое значение:

MsgSend()
Успешное завершение
Значение аргумента status, заданное сервером при вызове функции MsgReply*().
-1
Возникла ошибка (устанавливается errno), либо сервер вызвал MsgError*() и задал значение ошибки с помощью параметра ( errno, передаваемого в MsgError()).
MsgSend_r()
Успешное завершение
Значение аргумента status, заданное сервером при вызове функции MsgReply*().
negative value
Возникла ошибка ( errno не выставляется, возвращается отрицательная величина, заданная в секции "Коды ошибок") или сервер вызвал MsgError*() ( errno не выставляется, возвращается отрицательная величина параметра, переданного в MsgError()).

Коды ошибок:

EBADF
Соединение coid не существует или отключено от канала. Канал может быть уничтожен сервером или сетевым менеджером, если он не может обработать большое количество запросов.
EFAULT
Ошибка при попытке доступа ядра к предоставленным буферам. Это может произойти при приёме сообщения или при ответе.
EHOSTDOWN
Узел получателя не доступен (например, произошла ошибка при пересылке сообщения через Qnet).
EHOSTUNREACH
Взаимодействие с удалённым узлом невозможно (например, через Qnet).
EINTR
Функция была прервана сигналом.
ESRCH
Сервер завершил работу пока поток-отправитель был в состоянии SEND-блокирован или REPLY-блокирован.
ESRVRFAULT
Ошибка при попытке ядра получить доступ к предоставленным сервером буферам.
ETIMEDOUT
Функция прервана по тайм-ауту ядра. См. TimerTimeout().

Классификация:

ЗОСРВ «Нейтрино»

Точка остановки потока
Да
Обработчик прерываний
Нет
Обработчик сигналов
Да
В потоке
Да

Предостережения:

Максимальный размер сообщения определяется размером виртуального адресного пространства и зависит от процессорной архитектуры.

Тематические ссылки:

ConnectAttach(), MsgError(), MsgReceive(), MsgReceivev(), MsgReply(), MsgReplyv(), MsgSendnc(), MsgSendPulse(), MsgSendsv(), MsgSendsvnc(), MsgSendv(), MsgSendvnc(), MsgSendvs(), MsgSendvsnc(), name_open(), ThreadCancel(), TimerTimeout()




Предыдущий раздел: Описание API системной библиотеки