netlib.narod.ru | < Назад | Оглавление | Далее > |
Осталось рассмотреть еще несколько показательных функций, связанных с обработкой сигналов.
28981: Эта короткая системная функция позволяет процессам запрашивать о прибытии каких-либо сигналов не реального времени, пока они были заблокированы. Посредством передаваемого указателя функция возвращает набор разрядов, который указывает, какие это были сигналы.
28987: В основе этой функции лежит простая поразрядная операция AND с наборами blocked и signal процесса. Значение -EFAULT возвращается, если операция не удается, а значение 0 — если она выполняется успешно. Обратите внимание, что пребывание любых сигналов в состоянии задержки — т.е. то, пуст ли возвращаемый набор — не является критерием успешности операции.
28801: Функция do_sigation реализует интересную часть системной функции sigation. (Остальная часть реализована в функции sys_sigation, строка 2833.) Функция sigation представляет собой POSIX-эквивалент функции signal ISO С — она связывает действие с сигналом, чтобы действие выполнялось при получении сигнала процессом.
28806: Выполнение профилактических проверок: функция убеждается, что sig находится в допустимом диапазоне, что процесс не пытается связать действие с сигналом SIGKILL или SIGCONT. Просто процессам не разрешается изменять стандартное поведение этих двух сигналов. Однако, в отличие от обработчиков, устанавливаемых функцией signal, обработчики, устанавливаемые функцией sigaction, не принадлежат к типу SA_ONESHOT и поэтому не должны повторно устанавливаться при каждом вызове обработчика.
28811: Получает указатель на связанную с этим сигналом структуру struct k_sigaction.
28813: Посредством одного из двух переданных указателей, функция sigaction может вернуть старое действие. Это удобно для «помещения обработчиков в стек», когда обработчик временно замещается, а затем восстанавливается. Если значением указателя cast является не NULL, в него копируется старое действие. (Однако, это не приводит к копированию информации обратно в область пользователя; это должен сделать вызывающий процесс.)
28815: Если функции do_sigaction было передано действие, которое должно быть связанно с сигналом, теперь они связанны. Кроме того, сигналы SIGKILL и SIGSTOP должны быть удалены из маски действия, чтобы они не были заблокированы или перезаписаны.
28836: Как утверждается в заглавном комментарии, начинающемся в строке 28820, для приведения их в соответствие со стандартом POSIX следующие несколько строк должны быть несколько изменены, обеспечив, при необходимости, отмену некоторых ожидающих обработки сигналов. Мы потеряем не слишком много, пропустив подробности.
28694: Функция sys_rt_sigtimedwait ожидает прибытия сигнала, необязательно выходя из этого состояния по истечении указанного интервала времени. Не каждый сигнал будет принят; sigset_t, на которую указывает uthese, сообщает, каким сигналом интересуется вызывающий процесс.
28714: Объект uthese (скопированный в локальную переменную these) — это набор разрешенных сигналов, но примитивы ядра знают только как блокировать сигналы. Однако все в порядке: инвертирование набора разрешенных сигналов превращает их в набор сигналов, подлежащих блокированию, который затем можно использовать непосредственно.
28717: Если вызывающий процесс передал значение истечения времени ожидания, оно копируется в область пользователя и его значение подвергается профилактической проверке.
28726: Проверяет, дожидается ли обработки какой-либо сигнал — если да, то нет необходимости дожидаться сигнала. В противном случае вызывающий процесс должен подождать.
28731: Сохраняет старый блокируемый набор и временно ограничивает набор заблокированных сигналов в соответствие со значением, определенным переменной these.
28737: Если пользователь не передал никакого значения истечения времени ожидания, этим значением будет MAX_SCHEDULE_TIMEOUT (определенное переменной LONG_MAX, или значением 231–1 в строке 16228). Это не навсегда — значение истечения времени ожидания выражается в мигах, количестве тиков системных часов, частота которых равна 100 в секунду; таким образом, время ожидания составляет около 248 дней. (На 64-разрядном компьютере это значение составляет около 3 миллиардов лет.)
28739: Если пользователь передал значение истечения времени ожидания, оно преобразуется в миги. Часть этого выражения, которая следует за символом «+» — разумный способ выполнения округления до следующего мига. Смысл этого заключается в том, что функция timespec_to_jiffies (строка 18357) может выполнять округление в сторону уменьшения, в то время как ядро должно выполнять округление в сторону увеличения, поскольку оно должно выждать не меньше мигов, чем запросил пользователь. Ядро могло бы проверять, не выполнила ли функция timespec_to_jiffies округление в сторону уменьшения, но использованный способ дешевле и проще: оно добавляет один миг, если переданное пользователем значение не было нулем, и больше о нем не беспокоится. В любом случае, Linux не является операционной системой реального времени — когда пользователь просит о выжидании, ему гарантируется лишь то, что Linux выждет не меньше указанного интервала времени.
28742: Устанавливает состояние текущего процесса в TASK_INTERRUPTIBLE (см. главу 7). Функция schedule_timeout (строка 26577) используется для освобождения процессора; выполнение продолжится либо по истечении указанного времени, либо, если произойдет какое-либо другое событие, пробуждающее процесс (например, повторное получение сигнала).
28746: Процесс исходит из предположения, что он был пробужден сигналом. Функция sys_rt_sigtimedwait снова пытается вытолкнуть сигнал из очереди сигналов, дожидающихся этого процесса, и восстанавливает старый блокируемый набор.
28752: На данный момент функция все еще не знает, прибыл ли сигнал — мог быть получен сигнал, не требующий ожидания, сигнал мог прибыть во время ожидания или функция могла ожидать, а никакой сигнал не прибыл.
28753: Если сигнал прибыл, функция доставляет информацию процессу пользователя и возвращает номер сигнала.
28759: В противном случае, несмотря на то, что сигнал ожидается, никакой сигнал не прибыл. В этом случае функция возвращает либо -EAGAIN (указывая, что процесс пользователя может повторить попытку с этими же аргументами), либо -EINTR (указывая, что ее ожидание было прервано сигналом, который по какой-либо причине не смог быть доставлен).
netlib.narod.ru | < Назад | Оглавление | Далее > |