3

我在 Mac 上调试我的 HID 驱动程序代码中的崩溃,发现崩溃发生在 CFRunLoop 中。在驱动程序代码中,我打开与我的 HID 设备匹配的 VID 和 PID 的设备的 USB 句柄,然后使用 setInterruptReportHandlerCallback 函数为其设置中断回调,然后使用 CFRunLoopAddSource 调用将其添加到 CFRunLoop。在我调用关闭句柄时,我使用 CFRunLoopRemoveSource 释放它们,然后在 CFRunLoopSourceRef 上使用 CFRelease 。

当我尝试打开句柄等待一段时间(5ms)然后在循环中关闭句柄时会出现问题。

当我搜索问题时,我遇到了一个链接,在该链接中他们遇到了与我的http://lists.apple.com/archives/usb/.../msg00099.html类似的问题,他们使用 CFRunLoopSourceInvalidate 调用而不是删除源调用。当我在关闭句柄调用中将其更改为 Invalidate source 时,它​​修复了我的崩溃。我想知道崩溃之间有什么区别,为什么这个调用修复了我的崩溃?

感谢 jbsp72

4

1 回答 1

3

首先,让我谢谢你。我输入CFRunLoopRemoveSource谷歌,找到您的消息,这正是我试图解决的问题,而您通过调用的解决方案CFRunLoopSourceInvalidate也解决了我的问题。

CFRunLoopRemoveSource现在, an之间的区别CFRunLoopSourceInvalidate是:

  • CFRunLoopRemoveSource从您指定的特定运行循环中删除源。
  • CFRunLoopSourceInvalidate使源无效,并将其从添加的所有运行循环中删除。

现在,我怀疑与我遇到的崩溃相同,即添加源的运行循环已经消失,并且试图从中删除源会导致崩溃。实际上,__spin_lock就我而言,这是一个无限循环。

现在,运行循环如何消失?运行循环与线程相关联。你创建一个新线程,你有一个新的运行循环,自动。如果一个线程结束,run loop 就会随之消失。我将运行循环附加到的线程已退出,随后从运行循环中删除源会导致崩溃。

使运行循环无效解决问题的原因是因为它从它添加到的所有运行循环中删除了源,忽略了现在不再存在的运行循环。

于 2009-12-11T01:31:40.603 回答