Разница между CFRunLoopRemoveSource и CFRunLoopSourceInvalidate
Я отлаживал сбой в коде моего драйвера HID на Mac и обнаружил, что сбой произошел в CFRunLoop. В коде драйвера я открываю дескрипторы USB для устройств, которые соответствуют VID и PID, которые соответствуют моему устройству HID, а затем настраиваю обратный вызов для него с помощью функции setInterruptReportHandlerCallback, а затем добавляю его в CFRunLoop с помощью вызова CFRunLoopAddSource. В моем обращении к закрывающим дескрипторам я освободил их, используя CFRunLoopRemoveSource и затем CFRelease для CFRunLoopSourceRef .
Проблема возникает, когда я пытаюсь открыть маркеры, подождать некоторое время ( 5 мс) и затем закрыть маркеры в цикле.
Когда я искал проблему, я наткнулся на ссылку, где у них была похожая проблема с моей http://lists.apple.com/archives/usb/.../msg00099.html где они использовали вызов CFRunLoopSourceInvalidate вместо Remove Исходный звонок. Когда я изменил его на Invalidate source в моем вызове close handles, это исправило мой сбой. Я хотел знать, в чем разница между сбоем и почему этот вызов исправил мой сбой?
Спасибо jbsp72
1 ответ
Во-первых, позвольте мне поблагодарить вас. Я печатаю CFRunLoopRemoveSource
в Google найдите ваше сообщение, которое является именно той проблемой, которую я пытался решить, и ваше решение, позвонив CFRunLoopSourceInvalidate
вместо этого также решает мою проблему.
Теперь разница между CFRunLoopRemoveSource
CFRunLoopSourceInvalidate
является:
CFRunLoopRemoveSource
удаляет источник из указанного вами цикла выполнения.CFRunLoopSourceInvalidate
делает источник недействительным и удалит его из всех циклов выполнения, в которые он был добавлен.
Теперь сбой, который, как я подозреваю, такой же, как и у меня, состоит в том, что цикл выполнения, к которому был добавлен источник, исчез, а попытка удалить из него источник приводит к сбою. На самом деле, бесконечный цикл в __spin_lock
в моем случае.
Теперь, как может исчезнуть цикл выполнения? Циклы выполнения привязаны к потокам. Вы создаете новый поток, у вас есть новый цикл выполнения, автоматически. Если поток заканчивается, цикл выполнения исчезает вместе с ним. Поток, к которому я подключил цикл выполнения, завершился, и последующее удаление источника из цикла выполнения приводит к сбою.
Причина, по которой аннулирование цикла выполнения решает проблему, заключается в том, что он удаляет источник из всех циклов выполнения, к которым он был добавлен, игнорируя циклы выполнения, которые больше не существуют.