2012年10月20日土曜日

iOSウオッチドッグの存在

今まで全く気にしてなかったが、どうもiOS中にもウォッチドッグタイマーが存在するようである。

ウォッチドッグが何であるか、詳しくは調べてもらうとして、超簡単に書けば、
暴走防止のためのタイマーである。 組み込み機器ではウォッチドッグにひかかったら、
暴走や(周辺デバイス)無反応とみなしリセットをかけるのが普通である。
(正確には、プログラム的に一定時間以内にウォッチドッグタイマーをリセットしないと、ハードウエア的にリセットがかかるようになっている。)

某所の情報によると、iOSでもWebView周りには
  • Watchdog: 20秒(アプリケーション起動時など)
  • DNS: 30秒
  • TCP Connection: 75秒
  • NSURLConnection: 60秒
というウォッチドッグがいるらしい。
"0x8badfood"という例外コードを返してくるとか。"ate bad food"ということらしい。
ateはeatの過去形。発音が8=eightと同じである。

しかし、X-BASIC for iOS開発時の調査の結果、カーネルそのものに関わるタイムアウトも存在ようである。

以下のループをシミュレーター上で実行すると、約256秒でプログラムが落ちる。
while (1) {
#if 0
    NSDate *dt=[[NSDate alloc ]initWithTimeIntervalSinceNow:0.0];
    [[NSRunLoop currentRunLoop]runUntilDate:dt];
    [dt release];
#endif
 }
これで落ちるときはEXC_???(11)(code=0,subcode=0x0)となる。

#ifの中は有効無効どちらにしても変化なし。
また、この中にどれだけ長いCの処理を書いていたとしても、落とされてしまう。
 iOS5.1/6.0とも。

しかもこれ、Xcodeにつないでいる実機上やシミュレーター上でもLeakでトレースしていると発生しない。単独の実機ではHOMEに戻ってしまうし、シミュレーター上で普通に実行している場合は、上記エラーというかトラップを発生して止まる。

2013/11/10追記
iOS7シミュレーターでは発生しない様な気がする。Xcode5で改善された?

・・・

無限ループらしきところを警告しているつもりなのかもしれないが、定期的にcurrentRunLoopに戻しても発生するから、迷惑な事この上ない。
警告ならメッセージで出すべきであって、プログラムを落とすのはやりすぎ。

普通ウォッチドッグタイマーにはそれをリセットする機構があるが、iOSにはない。
ゆえに、iOSは組み込み機器的には使えない。
(iPadやiPod touchが安いから、筐体に組み入れて組み込み機器にしたらいいじゃん、という意見を見たことがあるが、iOSはこの件を含め、組み込み機器向けじゃない。組み込み機器なめんなよってな感じ。)

    ・・・

さらなる調査で、RunLoop内では、如何様にしてもループを回し続けるのはご法度と判明。必ず落ちる。
バッググラウンド内なら回し続けても大丈夫。でもバックグラウンドからからは表示させることができない。というか、表示や入力に関わるすべてのUI要素が使えなくなる。UIWebViewに至ってはレポートまで出力して落ちる。
だが、バックグラウンドからRunLoopに通信する方法が見つからない。
(KVOは同一スレッド内で実行されるのでダメ。 Notificationもおそらく同様。)
これさえあれば何とかならんでもないのだが。

KVOの通知でフラグを立て、先のループ内で表示するという手を考えた。
while (1) {
    NSDate *dt=[[NSDate alloc ]initWithTimeIntervalSinceNow:0.1]; // 0.0はだめ
    [[NSRunLoop currentRunLoop]runUntilDate:dt]
    [dt release];
    if (flag) {
       // 表示
    }
 }
実際にこれで表示が出るには出る。が、秒1回くらいならずっとOKなのだが、秒30回くらいの速度でしばらく回していると表示が出なくなる。どうも、NSRunLoopの行から帰ってこないようだ。RunLoopに入りっぱなしになるという感じ。バグじゃろうこれは。

→アップルのドキュメントの中にRunLoopにスレッドを接続する方法を発見。
何とかUIViewの表示だけは出来るようになった。が、問題はUIViewだけじゃなくUITextFiled等も含む全UI要素に関わるので対応が非常に大変。
→実機で落ちなけりゃそれでOKで無視することにした。


0 件のコメント:

コメントを投稿