CFRunLoopRemoveSource 和 CFRunLoopSourceInvalidate 之间的区别
我在 Mac 上调试 HID 驱动程序代码中的崩溃,发现崩溃发生在 CFRunLoop 中。 在驱动程序代码中,我打开与 VID 和 PID 匹配的设备的 USB 句柄(与我的 HID 设备匹配),然后使用 setInterruptReportHandlerCallback 函数为其设置中断回调,然后使用 CFRunLoopAddSource 调用将其添加到 CFRunLoop。 在对关闭句柄的调用中,我使用 CFRunLoopRemoveSource 释放它们,然后使用 CFRunLoopSourceRef 上的 CFRelease 释放它们。
当我尝试打开句柄等待一段时间(5毫秒)然后循环关闭句柄时,就会出现问题。
当我搜索问题时,我发现了一个链接,其中他们有与我类似的问题 http://lists.apple.com/archives/usb/.../msg00099.html 他们使用 CFRunLoopSourceInvalidate 调用而不是删除源调用。 当我在关闭句柄调用中将其更改为无效源时,它修复了我的崩溃。 我想知道崩溃之间有什么区别以及为什么这个调用修复了我的崩溃?
谢谢 杰布斯普72
I was debugging a crash in my HID driver code on the Mac and found that the crash happened in the CFRunLoop. In the driver code I open the USB handles for the devices which match the VID and the PID which match my HID device and then set up an Interrupt call back for it using setInterruptReportHandlerCallback function and then add it to the CFRunLoop using CFRunLoopAddSource call. In my call to the close handles I freed them up using CFRunLoopRemoveSource and then a CFRelease on the CFRunLoopSourceRef .
The problem occurs when I try to Open the handles wait for a while( 5ms) and then close the handles in a loop.
When I searched for the problem I came across a link where they had a similar problem to mine http://lists.apple.com/archives/usb/.../msg00099.html where they had used CFRunLoopSourceInvalidate call instead of teh Remove Source call. When I changed it to Invalidate source in my close handles call, it fixed my crash. I wanted to know what is the difference between the crash and why this call fixed my crash?
Thanks
jbsp72
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
首先,我要谢谢你。 我在 google 中输入
CFRunLoopRemoveSource
,找到您的消息,这正是我试图解决的问题,而您通过调用CFRunLoopSourceInvalidate
的解决方案也解决了我的问题。现在,
CFRunLoopRemoveSource
和CFRunLoopSourceInvalidate
之间的区别是:CFRunLoopRemoveSource
删除了来自您的特定运行循环的源
指定。
CFRunLoopSourceInvalidate
渲染来源无效,将删除它
从所有运行循环中,
添加。
现在,崩溃(我怀疑与我遇到的崩溃相同)是添加源的运行循环已经消失,并且尝试从中删除源会导致崩溃。 实际上,在我的例子中,
__spin_lock
是一个无限循环。现在,运行循环怎么会消失呢? 运行循环与线程绑定。 您创建一个新线程,就会自动获得一个新的运行循环。 如果线程结束,运行循环也会随之消失。 我附加运行循环的线程已退出,随后从运行循环中删除源会导致崩溃。
使运行循环无效之所以能解决问题,是因为它从添加到的所有运行循环中删除源,忽略现在不再存在的运行循环。
First, let me thank you. I type
CFRunLoopRemoveSource
in google, find your message which is exactly the problem I was trying to solve, and your solution by callingCFRunLoopSourceInvalidate
instead also solves my problem.Now, the difference between
CFRunLoopRemoveSource
anCFRunLoopSourceInvalidate
is:CFRunLoopRemoveSource
removes thesource from the specific run loop you
specify.
CFRunLoopSourceInvalidate
renders thesource invalid, and will remove it
from all the run loops where was
added.
Now, the crash, which I suspect is the same as the one I got, is that the run loop the source was added to has disappeared, and trying to remove the source from it results in a crash. Actually, an infinite loop in
__spin_lock
in my case.Now, how can a run loop disappear? Run loops are tied to threads. You create a new thread, you have a new run loop, automatically. If a thread ends, the run loop disappears with it. The thread I attached the run loop to has exited, and subsequently removing the source from the run loop results in the crash.
The reason why invalidating the run loop solves the problem is because it removes the source from all the run loops it was added to, ignoring run loops that now do not exist anymore.