DBusの応答にコールバック関数を使用しようとすると、うまく機能しているメインループの作成に取り掛かることになります。低レベルのDBus C APIのメインループ
私がやりたいことは単純ですが、DBus呼び出しを行い、応答が来たときに呼び出される関数を指定します。これは、回答が計算されて到着するまで、スレッド全体をブロックしたくないからです。
まずdbus_connection_send_with_reply(..)を使用してDBusPendingCallを取得した後、dbus_pending_call_set_notify(..)を使用してコールバック関数を指定します。これを行う前に、バスに接続するとき、私は応答を待ってコールバック関数を呼び出すべき別のスレッドを開始しました。私は例を全く見つけず、このようにdbusメインループをどのように設計すべきかについての非常に良い文書はありません。私が試してみました:私はMY_DBUS_STATUS_STOPPINGにdbus->ステータスフラグを設定し、スレッドが参加するのを待つことにより、アプリケーションを停止しよう
:
// Main dbus loop handling data transfer and callbacks.. void *dbus_main(void *args) { my_dbus dbus = (my_dbus)args; while (MY_DBUS_STATUS_STOPPING != dbus->status && dbus_connection_read_write_dispatch(dbus->conn, -1)) ; return 0; } // Start the dbus main loop in a new thread void dbus_main_start(my_dbus dbus) { if (!pthread_create(&dbus->th, NULL, dbus_main, dbus)) { // PRINT ERROR } }
私の問題は二つのことです。スレッドがdbus_connection_read_write_dispatch(..)関数でブロックされている場合、これは機能しません。私はアプリを速く停止したい場合、私は非常に短いタイムアウトを指定する必要があります。ブロックされたスレッドを別の方法で起きさせることはできませんか?
さらに深刻なことに、このコードでは、私が呼び出すメソッドからコールバックを取得しません。 stdoutに書き込むためにfprintf(..)を追加すると、私は突然コールバックを取得する可能性があります。それは非常にランダムなので、デッドロックのいくつかの種類のようですか?私は、dbus_connection_flush(..)の間にメッセージを送信し、_set_notify(..)関数でコールバックを追加することを試みました。違いはありません...しかし、同じ場所でstdoutにいくつかの文字を印刷すると、問題が修正されます。 dbus-main-loop instedの空の ";"のstdoutへの出力すなわち_block(..)を使用していない、非同期メソッドと一緒に低レベルのdbusのAPIを使用する例があり、誰だから... ...時々
をトリックを行うようだ??