我正在 Mac 上调试 HID 驱动程序代码中的崩溃,发现崩溃发生在 CFRunLoop 中。在驱动程序代码中,我打开与 VID 和 PID 匹配的设备的 USB 句柄(与我的 HID 设备匹配),然后使用 setInterruptReportHandlerCallback 函数为其设置中断回调,然后使用 CFRunLoopAddSource 调用将其添加到 CFRunLoop。在调用关闭句柄时,我使用 CFRunLoopRemoveSource 释放它们,然后使用 CFRunLoopSourceRef 上的 CFRelease 释放它们。
当我尝试打开句柄等待一段时间(5ms)然后循环关闭句柄时,就会出现问题。
当我搜索问题时,我发现了一个链接,其中他们有与我类似的问题 http://lists.apple.com/archives/usb/.../msg00099.html他们使用 CFRunLoopSourceInvalidate 调用而不是删除源调用。当我在关闭句柄调用中将其更改为无效源时,它修复了我的崩溃。我想知道崩溃之间有什么区别以及为什么此调用修复了我的崩溃?
谢谢 jbsp72
最佳答案
首先,我要谢谢你。我在 google 中输入 CFRunLoopRemoveSource
,找到您的消息,这正是我试图解决的问题,而您通过调用 CFRunLoopSourceInvalidate
的解决方案也解决了我的问题。
现在,CFRunLoopRemoveSource
和 CFRunLoopSourceInvalidate
之间的区别是:
CFRunLoopRemoveSource
删除 来自您的特定运行循环的源 请指定。CFRunLoopSourceInvalidate
渲染 来源无效,将删除它 从所有运行循环中, 添加。
现在,崩溃(我怀疑与我遇到的崩溃相同)是添加源的运行循环已经消失,并且尝试从中删除源会导致崩溃。实际上,在我的例子中,__spin_lock
是一个无限循环。
现在,运行循环怎么会消失呢?运行循环与线程绑定(bind)。您创建一个新线程,就会自动获得一个新的运行循环。如果线程结束,运行循环也会随之消失。我附加运行循环的线程已退出,随后从运行循环中删除源会导致崩溃。
使运行循环无效可以解决问题的原因是,它从添加到的所有运行循环中删除源,忽略现在不再存在的运行循环。
关于macos - CFRunLoopRemoveSource 和 CFRunLoopSourceInvalidate 之间的区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/709526/