Разница между CFRunLoopRemoveSource и CFRunLoopSourceInvalidate - PullRequest
3 голосов
/ 02 апреля 2009

Я отлаживал сбой в коде моего драйвера HID на Mac и обнаружил, что сбой произошел в CFRunLoop. В коде драйвера я открываю дескрипторы USB для устройств, которые соответствуют VID и PID, которые соответствуют моему устройству HID, а затем настраиваю обратный вызов для него с помощью функции setInterruptReportHandlerCallback, а затем добавляю его в CFRunLoop с помощью вызова CFRunLoopAddSource. В моем обращении к дескрипторам закрытия я освободил их, используя CFRunLoopRemoveSource, а затем CFRelease для CFRunLoopSourceRef.

Проблема возникает, когда я пытаюсь открыть ручки, подождать некоторое время (5 мс), а затем закрыть их в цикле.

Когда я искал проблему, я наткнулся на ссылку, где у них была проблема, аналогичная моей http://lists.apple.com/archives/usb/.../msg00099.html, где они использовали вызов CFRunLoopSourceInvalidate вместо вызова Remove Source. Когда я изменил его на Invalidate source в своем вызове close handles, это исправило мой сбой. Я хотел знать, в чем разница между сбоем и почему этот вызов исправил мой сбой?

Спасибо jbsp72

1 Ответ

3 голосов
/ 11 декабря 2009

Во-первых, позвольте мне поблагодарить вас. Я набираю CFRunLoopRemoveSource в Google, чтобы найти ваше сообщение, которое является именно той проблемой, которую я пытался решить, и ваше решение, позвонив по номеру CFRunLoopSourceInvalidate, также решает мою проблему.

Теперь разница между CFRunLoopRemoveSource и CFRunLoopSourceInvalidate составляет:

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

Теперь сбой, который, как я подозреваю, такой же, как и у меня, состоит в том, что цикл выполнения, к которому был добавлен источник, исчез, а попытка удалить из него источник приводит к сбою. На самом деле, бесконечный цикл в __spin_lock в моем случае.

Теперь, как может исчезнуть цикл выполнения? Циклы выполнения привязаны к потокам. Вы создаете новый поток, у вас есть новый цикл выполнения, автоматически. Если поток заканчивается, цикл выполнения исчезает вместе с ним. Завершился поток, к которому я прикрепил цикл выполнения, и последующее удаление источника из цикла выполнения приведет к сбою.

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

...