2015/05/16

GLibのイベントループ

BlueZのgatttoolを変更して、Central側の動作確認ツールを作ろうとしている。
まずはconnectさせて、connectしたらprimaryを見るだけのところを作っているのだが、これがなかなかうまくいかない。

connect実行後に接続状態を監視するスレッドを作って、本体はjoinで待たせている。
しかし、接続状態が変化しないのだ。
Peripheralは接続が完了しているので、connect自体は動いている。
volatileつけてなかったから最適化されてしまったのかと思ったが、そもそもconnect完了のコールバックが呼ばれていない。

おそらく、joinで待たせているためGLibのイベントループが動かず、コールバックが呼ばれないのだと思っている。
なので、状態監視しているスレッドの中でイベントループを回す関数でも呼び出してやればよいと思うのだが、それに該当するAPIが見つけられていない。

軽く調べておこう。


GLibの本家資料は、たぶんここだろう。
GNUかGNOME。

今回やりたイベントループのことは、ここになるか。
https://developer.gnome.org/glib/stable/glib-The-Main-Event-Loop.html#glib-The-Main-Event-Loop.description
イベントはファイルディスクリプタとタイムアウトとなっている。
Wikipediaの説明でもそう書いてあるので、そうなんだろう。

なので、今回やりたいような「この変数がこの値になったら」みたいなのはイベントにできなさそうだ。
そういうことをしたければ、自分でfdつくって値の変更タイミングで書込むイベントにするか、タイマで監視するようなしくみにするか・・・。

 

APIを見てると、g_idle_add()というのがあった。
優先度の高いイベントが無いときに呼ばれるそうだ。
試しにやってみると、確かにそういう動きをする。
何かイベントが発生し終わったときに呼ばれるのではなく、アイドル状態だったら呼び出され続けるようだ。
"add"なので、BlueZでアイドル状態を監視するようになっていたとしても追加できる。

g_idle_add()で気になったのは、g_idle_source_new()。
このAPIは呼び出していないのだが、g_idle_add()は使えた。
BlueZをgrepしても出てこないので、たぶん誰も呼び出していないのだが、それでよいのだろうか?

 

こちらを見て気付いたのだが、g_main_context_iteration()を呼ぶことでイベントループを1回だけ回せるようだ。
PyGTKで重い処理をしているときにGUIを固まらせないための手法をまとめる - 試験運用中なLinux備忘録


そういう視点でGLib Referenceを読むと、Descriptionにアイドルのこともシングルなイベントループ呼び出しのことも書いてあった。
英語を読む力が弱いのは課題だな・・・。

1 件のコメント:

  1. 貴重な情報ありがとうございます
    これ使えば、ウインドウ作った途端にダイアログ出すとかできそうです

    返信削除

コメントありがとうございます。
スパムかもしれない、と私が思ったら、
申し訳ないですが勝手に削除することもあります。

注: コメントを投稿できるのは、このブログのメンバーだけです。