Ядро Linux в комментариях




Real_msgsnd - часть 3


В очереди нет свободного места. Если в структуре msgflg установлен бит IPC_NOWAIT, вызывающая программа не должна ждать, пока это случится, поэтому возвращается ошибка EAGAIN.

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

Если для процесса нет никакого сигнала, процесс переходит в состояние ожидания до тех пор, пока не будет активизирован в результате поступления сигнала или удаления сообщения из очереди. После активизации процесса он снова пытается выполнить запись в очередь.

Распределение достаточного пространства как для заголовка очереди сообщений (объект struct msg), так и для тела сообщения; как было упомянуто ранее, тело сообщения будет записано непосредственно после заголовка сообщения. Значение msg_spot заголовка будет указывать на место сразу после заголовка, где должно находиться тело сообщения.

Копирует тело сообщения из пространства пользователя.

Повторная проверка исправности очереди сообщений. Вход msgque мог быть изменен другим процессом в то время, когда процесс находился в состоянии ожидания после выполнения строки , поэтому msq нельзя считать действительным указателем до тех пор, пока не будет выполнена его проверка.

Несмотря на это, создается впечатление, что здесь возможна ошибка. А что, если очередь сообщений будет уничтожена и по тому же индексу массива будет развернута другая очередь сообщений, прежде чем текущий процесс достигает этой точки? Это не может произойти на однопроцессорном компьютере, поскольку функция freeque, которая уничтожает очереди сообщений (строка ), активизирует все процессы, ждущие в очереди, перед ее уничтожением и не перейдет эту точку, пока не закончит свою работу функция real_msgsnd (функция freeque рассматривается далее в этой главе).

Однако все же, кажется, что риск этого на компьютерах с симметричной мультипроцессорной архитектурой невелик.

Если бы это произошло, значение msgque[id] не равнялось бы IPC_UNUSED или IPC_NOID, но память, на которую указывает msq, была бы освобождена функцией freeque, поэтому в строке происходила бы разадресация недействительного указателя.

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

Активизирует все процессы, которые могут ожидать поступления сообщения в эту очередь, а затем возвращает 0 в случае успеха.




Содержание  Назад  Вперед