tags:

views:

147

answers:

1

Hi,

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

A: 

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 calling CFRunLoopSourceInvalidate instead also solves my problem.

Now, the difference between CFRunLoopRemoveSource an CFRunLoopSourceInvalidate is:

  • CFRunLoopRemoveSource removes the source from the specific run loop you specify.
  • CFRunLoopSourceInvalidate renders the source 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.

Thomas