#c #driverkit #macos-system-extension
Вопрос:
У меня есть драйвер Driverkit, который заботится об USB-устройстве. Драйвер распаковывает данные в USB — пакетах и записывает их в буферы, которые совместно используются приложением и драйвером. Общие буферы создаются приложением с IOConnectCallAsyncMethod
помощью . Когда буфер готов к использованию приложением, драйвер вызывает IOUserClient::AsyncCompletion
OSAction
объект. OSAction
Объект также создается в результате вызова IOConnectCallAsyncMethod
приложения. На OSAction
каждый общий буфер приходится один объект.
В случае ошибки в механизме, который обрабатывает события в приложении, я говорю водителю прекратить вызывать OSAction
объекты, и поток, который обрабатывает события в приложении, останавливается. На данный момент я не могу быть уверен, что обработал все события в приложении, и когда я отправляю сообщение водителю для повторного запуска, я хочу быть уверен, что никакие события, произошедшие до остановки, не находятся в очереди для обработки приложением.
Я рассмотрел OSAction::Cancel
, который позволяет передавать обработчик, который следует вызывать при отмене обратного вызова. В документации к этому методу указано, что система будет вызывать блок обработчика для вызова после завершения любых обратных вызовов в полете.
Что означает обратный вызов «в полете«?
Я вызываю Cancel
все OSAction
объекты и уменьшаю счетчик для каждого OSAction
объекта, чтобы отслеживать завершение отмены (аналогично этому примеру проекта от Apple). Проблема в том, что я не вижу, что блок вызывается.
Когда я могу ожидать, что блок будет вызван? Несколько различных ситуаций, о которых я могу думать, это:
- И
OSAction
это никогда не передавалосьAsyncCompletion
. - Сообщение
OSAction
, которое было переданоAsyncCompletion
, но приложение не обработало событие. - После того , как
OSAction
это было переданоAsyncCompletion
, приложение начало обрабатывать событие, но приложение еще не завершило работу с событием.
Мне также интересно, какая очередь отправки в драйвере будет использоваться для вызова блока.