Внутреннее устройство ядра Linux 2.4

       

Sys_msgsnd()


Функция sys_msgsnd() принимает через входные параметры ID очереди сообщений (msqid), указатель на буфер типа (msgp), размер передаваемого сообщения (msgsz) и флаг - признак разрешения перехода процесса в режим ожидания (msgflg). Каждая очередь сообщений имеет две очереди ожидания для процессов и одну очередь ожидающих сообщений. Если в очереди ожидания имеется процесс, ожидающий данное сообщение (msgp), то это сообщение передается непосредственно ожидающему процессу, после чего процесс-получатель "пробуждается". В противном случае производится проверка - достаточно ли места в очереди ожидающих сообщений и если достаточно, то сообщение сохраняется в этой очереди. Если же места недостаточно, то процесс-отправитель ставится в очередь ожидания. Более подробное освещение этих действий приводится ниже:

  • Производится проверка адреса пользовательского буфера и типа сообщения, после чего содержимое буфера копируется вызовом во временный буфер msg типа . Инициализируются поле типа сообщения и поле размера сообщения.
  • Выполняется глобальная блокировка очереди сообщений и по ID очереди отыскивается ее дескриптор. Если такой очереди не было найдено, то в вызывающую программу возвращается код ошибки EINVAL.
  • В функции (вызывается из msg_checkid()) проверяется ID очереди сообщений и права доступа процесса вызовом .
  • Производится проверка - достаточно ли места в очереди ожидающих сообщений для помещения туда данного сообщения. Если места недостаточно, то выполняются следующие действия:

  • Если установлен флаг IPC_NOWAIT (в msgflg) то глобальная блокировка очереди сообщений снимается, память, занимаемая сообщением, освобождается и возвращается код ошибки EAGAIN.
  • Вызовом текущий процесс помещается в очередь ожидания для процессов-отправителей. Так же снимается блокировкаи вызывается планировщик schedule() который переведет процесс в состояние "сна".
  • После "пробуждения" снова выполняется глобальная блокировка очереди сообщений и проверяется ID очереди сообщений. Если во время "сна" очередь была удалена, то процессу возвращается признак ERMID.

  • Если для данного процесса имеются какие либо сигналы, ожидающие обработки, то вызовом процесс изымается из очереди ожидания для процессов-отправителей, блокировка снимается, вызывается для освобождения буфера сообщения и процессу возвращается код EINTR. Иначе осуществляется переход на выполнение необходимых проверок.


  • Для передачи сообщения напрямую процессу-получателю вызывается .


  • Если процессов-получателей, ожидающих данное сообщение, не было обнаружено, то сообщение msg помещается в очередь ожидающих сообщений (msq->q_messages). Обновляются поля q_cbytes и q_qnum в дескрипторе очереди сообщений, а так же глобальные переменные msg_bytes и msg_hdrs, содержащие в себе общий объем сообщений в байтах и общее количество сообщений.


  • Если сообщение было благополучно передано процессу-получателю либо поставлено в очередь, то обновляются поля q_lspid и q_stime в дескрипторе очереди и освобождается глобальная блокировка.



  • Содержание раздела