Да, этот код на самом деле гонка , между вызовами prepare_to_wait
и schedule
это должна быть проверка на condition
(и взлом, если он удовлетворен).
Довольно забавно, что в следующем описании книга ссылается (на странице 60) на реализацию функции inotify_read()
в fs/notify/inotify/inotify_user.c
файле:
DEFINE_WAIT(wait);
...
while (1) {
prepare_to_wait(&group->notification_waitq,
&wait,
TASK_INTERRUPTIBLE);
if (<condition>) // very simplified form of checks
break;
if (signal_pending(current))
break;
schedule();
}
finish_wait(&group->notification_waitq, &wait);
...
, которая, по словам автора, «следует шаблону»:
Эта функция следует шаблону, представленному в нашем примере. Основное отличие состоит в том, что он проверяет условие в теле оператора while()
l oop, а не в самом выражении while()
. Это связано с тем, что проверка условия сложна и требует захватывающих блокировок. L oop завершается через break
.
Однако этот код демонстрирует другой шаблон , который проверяет условие между вызовами prepare_to_wait
и schedule
. И этот код на самом деле правильный (без гонок). Также этот код не использует add_wait_queue
, что является лишним при наличии prepare_to_wait
.
В другой книге того же автора, Linux Разработка драйверов (3-я версия), использование очередей ожидания кажется если быть более точным. См., Например, главу 6, Расширенные операции с драйверами Char.