ウェブブラウザ開発ブログ
 
ウェブブラウザ開発ブログ

マルチスレッド/プロセス対応途中の公開

マルチスレッド/プロセス対応中ですが、途中のものを公開しています。途中なので通常使用はお勧めしません。 更新履歴 download 主要機能 ドロップアクション、マウスジェスチャ、IEプラグイン、スクリプト、閉じたタブの復元、ステータスバー。。など のほとんどがまだ動作しません。これを全て対応してから出すと、とても時間がかかるので、順次出していくことにします。大体対応が終わったとき、0.8.1として出すつもりです。いまはスレッド/プロセスの制限数がありませんが、数の最大値は設定可能にします。ためしにマルチプロセスのとき子プロセスをタスクマネージャから終了しても、アプリは落ちず動作し続けます。 どのようにマルチスレッド/プロセスを対応しているか気になる人もいるかと思うので、実装イメージを書きます。まず、概要をいうとプロキシオブジェクトの動作を作っています。MDIChildFrameはメインスレッドで動かし、Frameの子Windowは、別スレッドで動かします。 Anciaでは、オブジェクト間でさまざまな処理を行えるよう struct __declspec(novtable) ICmdTarget : public IUnknown { STDMETHOD(CmdExec)(long cmdId, long cmdExecOpt, OPTIONAL VARIANT* arg1, OPTIONAL VARIANT* arg2, OPTIONAL VARIANT* arg3, OUT VARIANT* result) = 0; }; というIOleCommandTargetのようなインターフェースで内部動作を作っています。ここで、MDIChildFrame <-> Child間をICmdTargetでやり取りするようマルチスレッド対応で変更しました(いままでは、MDIChildFrameがすべて子Window処理を行っていた)。やり取りで、シングルスレッドのときは、直に相手のCmdExecを呼び、マルチスレッド/マルチプロセスのときは、プロキシオブジェクトを通してIPC通信で相手のCmdExecを呼ぶようにした、というのが簡単な動作説明です。単純なマーシャル的なものを作っているのと同じでしょうか。 ほとんどのプロキシ間コマンドは、CmdExecからIPC通信で相手側の処理を呼び出す HRESULT IpcCmdExec(HWND hWndTarget, IpcInfo* pIpcInfo, int fFlags, UINT idCmd, LPVARIANT arg1 = 0, LPVARIANT arg2 = 0, LPVARIANT arg3 = 0); というのを呼ぶだけで、すむと思っていたんですが、中にはそう簡単にいかないものがあり、時間はかかりそうです。
この投稿を読む

途中2

シングルスレッド、マルチスレッド、マルチプロセスを意識しないで動作するよう内部設計を変えている途中で、まあそれなりにうまくいくかもというところです。シングルスレッドでは多少遅くなるかもしれませんが、1つ、2つAPI呼び出しが増えてもそれど遅くならないでしょう。 タスクバーサムネイルが出るようになりましたが、スレッド(おそらくプロセスも)が違うとITaskbarList3::SetTabOrderが失敗してしまいました。仕方ないので、SetTabOrderのhwndInsertBeforeにNULLを渡して、後ろにどんどんずらしていく、というのは大変そうなのでどうしよう、、 追記)SetTabOrderの失敗は、間違ったHWNDを渡しているだけでした。SetTabOrderって別のプロセスがRegisterTabしても成功してます。
この投稿を読む

途中

ぜんぜんまだまだですが、やっとページの表示まで行きました。ここからが大変で、IE拡張機能、スクリプト、IPCでの状態の同期等、いろいろあります。。MDIのマルチプロセス/スレッドは、そもそもあまり見かけないので、どうなるか、致命的なことが無ければいいのですが、、
この投稿を読む

継続中。。

更新履歴 download マルチプロセススレッド対応でグローバル変数をできるだけ使用しない修正で、内部はかなり変更になっています。なのでシングルスレッド版として一先ずリリースしました。いまブログも0.8.0で書いていますが、大丈夫そうです。致命的な不具合が無ければ、おそらく最後のシングルスレッド版になると思います。 マルチスレッドのとき、ステータスバーのメッセージを、親スレッドで出すが、子スレッドで出すか、メニュー関係のメッセージはメニューを出したスレッドで処理した方がいいんじゃないかなど、いろいろ悩みどころです。
この投稿を読む

うーん

やっぱりそう簡単にはいかないですね。全体的にオブジェクトの持ち方を見直さないと。。Anciaはなんとか今月中に更新したいところです。
この投稿を読む

スクロール

子スレッドでIEコンポーネントを動かすとホイールスクロールが少し引っかかるような動作になることで、 子スレッドをポップアップウインドウとすると、なぜか引っ掛かりが無くなる スムーズスクロールoffで改善する FEATURE_BROWSER_EMULATIONでIE8レンダリングモードとすると多少改善する ということが分かりました。1から親子スレッド間のウインドウや描画が関係してそうな雰囲気ですが、なぜかがまったく分からないので、スクロール引っかかりが気になる場合は、インターネットオプションで2をしてもらうことになりそうです。theworldやMaxthonはポップアップウインドウにしているようです。
この投稿を読む

マルチプロセススレッド試作物

MultiProcessThread.zip メッセージベース+共有メモリでのIPCを使用したマルチプロセス、スレッドのプロトタイプです。機能は、WTLのタブブラウザサンプル相当しかありません。exeの同じディレクトリにファイルthreadがあるとマルチスレッド、ないとマルチプロセスで動作します。 プロセス、スレッドの動作の違いは、制御の作成がCreateProcess/CreateThreadか、マーシャリングをプロセス間/プロセス内としているかぐらいしかありません。ただスレッドの場合は、共有メモリではなくヒープを使用するなど、改善部分はあります。タブのタイトル更新、アドレスバーのURL更新はIPC、戻る/進む/ホーム/中止は、マーシャリングしたポインタで行っています。マーシャリングはテストで毎回行っています。マウスホイールでのスクロール対応も入れてます。 IPCを決めるとき、名前つきパイプにしようと思ったんですが、パイプだとメッセージボックスやダイアログを表示中だとrecvできないので、UIスレッドとは別スレッドにすることになり、やめました。メッセージベースで単純なSendとし、再入可能の動作にする予定です。ただ固まっている子プロセスのウインドウへメインプロセスのウインドウからタイムアウトなしのSendが行われるとメインプロセスも固まってしまうため、Windowsが内部で自動的にSendしているものは、固まりを防げないかもしれません。たしか、同じホストで、マーシャリングしたポインタを介した呼び出しもメッセージベースなので、呼び先のタブが固まっていると、呼び元に制御が返らない、はずです。マーシャリングするときも応答があるときに行うようにしなければならないようです。 プロトタイプの公開はこれまでとし、次はプロトタイプをいじりながらAnciaに組み込んでいければというところです。
この投稿を読む
ページ上部に戻る