これはバグちゅか馬鹿だろ

amelia2007-05-12

先日のサブスレッドが固まる現象はメッセージデッドロックが原因でした。
優先度云々での対処は、たまたま動いていただけであり、固まる不具合は残っていて、色々と原因を探ってみたところ、やはりメッセージデッドロック的な現象であり、Spyで監視してみたところ、案の定メッセージが同期発行されていました。

そもそも、何故にサブスレッド(ワーカスレッドでありUIスレッドではない)から意図していないメッセージが同期発行されているのかを追ってみると、ラッパライブラリ内で隠しウィンドウを生成しており、WM_PARENTNOTIFYがメインスレッドにSendMessage()されていた罠。

まぁ、簡単に言えば、死んでくれちゅうこった。

ちゅことで、MsgWaitForMultipleObjects()を使用しメッセージを受け流すように修正したところ、意図する動作となった訳です。

全然関係ないけど、スレッドのエレガントな停止方法て、PostThreadMessage()でWM_QUIT(又はWM_INTERRUPTとかのWM_USER+n作ったりして)飛ばして、サブスレッド側でPeekMessage()にて検出しコールバックを抜けるちゅうやつだと思っているんだけど、開発メンバの中にはベタにフラグ使ったり(今回の不具合が発覚したソースがまさにそう)、イベントフラグ + WaitFor〜検知使ったりで、色々な方法があるんだなぁと思うのと同時に、こうやってバリエーション豊かに停止方法が溢れると単純にバグの入り込む余地が増えるんですけど。。みたいな。そいや、どこかのサイトでスレッドを起動しただけではメッセージキューは作成されていなくて、PeekMessage()などのメッセージキュー操作系関数を実行しないと作成されないとかいう文献を読んだ記憶が。メッセージキューが作成されていない状態でPostThreadMessage()したらどうなるんだろう(わくわく