3

Mac で HID ドライバー コードのクラッシュをデバッグしていたところ、CFRunLoop でクラッシュが発生していることがわかりました。ドライバー コードでは、HID デバイスに一致する VID と PID に一致するデバイスの USB ハンドルを開き、setInterruptReportHandlerCallback 関数を使用して割り込みコールバックを設定し、CFRunLoopAddSource 呼び出しを使用して CFRunLoop に追加します。クローズ ハンドルの呼び出しでは、CFRunLoopRemoveSource を使用して解放し、次に CFRunLoopSourceRef で CFRelease を使用しました。

この問題は、ハンドルを開こうとしてしばらく (5ms) 待ってから、ループでハンドルを閉じようとすると発生します。

私が問題を検索したとき、彼らが私と同様の問題を抱えていたリンクに出くわしましたhttp://lists.apple.com/archives/usb/.../msg00099.htmlここで、削除の代わりに CFRunLoopSourceInvalidate 呼び出しを使用していましたソース呼び出し。close handles 呼び出しで Invalidate source に変更すると、クラッシュが修正されました。クラッシュの違いと、この呼び出しでクラッシュが修正された理由を知りたいですか?

ありがとうjbsp72

4

1 に答える 1

3

まずはお礼を言わせてください。私CFRunLoopRemoveSourceはグーグルで入力し、まさに私が解決しようとしていた問題であるあなたのメッセージを見つけ、CFRunLoopSourceInvalidate代わりに電話することによるあなたの解決策も私の問題を解決します.

との違いは次CFRunLoopRemoveSourceのとおりです。CFRunLoopSourceInvalidate

  • CFRunLoopRemoveSource指定した特定の実行ループからソースを削除します。
  • CFRunLoopSourceInvalidateソースを無効にし、追加されたすべての実行ループからソースを削除します。

さて、クラッシュは、私が得たものと同じであると思われますが、ソースが追加された実行ループが消え、そこからソースを削除しようとするとクラッシュします. 実際、__spin_lock私の場合は無限ループです。

では、どうすれば実行ループをなくすことができるでしょうか? 実行ループはスレッドに関連付けられています。新しいスレッドを作成すると、新しい実行ループが自動的に作成されます。スレッドが終了すると、実行ループも一緒に消えます。実行ループをアタッチしたスレッドが終了した後、実行ループからソースを削除すると、クラッシュが発生します。

実行ループを無効にすることで問題が解決する理由は、ソースが追加されたすべての実行ループからソースが削除され、現在存在しない実行ループが無視されるためです。

于 2009-12-11T01:31:40.603 に答える