ExecAt でデッドロックNo.07474
山紫水明 さん 03/11/29 11:52
 
  こんにちは,山紫水明です。

 昨日のサブフォルダ検索に少し関連することですが,
 エディタウィンドウを開いて,

loaddll "TKinfo.dll";
$s = "abc@defg";
##main = dllfunc("MainWnd");
#n = dllfunc("ExecAt", ##main, "SetFindPack", "(\"" + $s + "\",target=all),
inmail=2");
if( dllfunc("ExecAt", ##main, "FindDownInclude") ) message "ありました";
else message "ありません";
endmacro;

というマクロで $s にいろいろ値を入れて動かす時,問題がない場合と,「マク
ロ実行の退避」のダイアログが出て,マクロ実行のキャンセルを押すと,
「TKINFO.DLL:ExecAt でデッドロックが発生しました」というエラーメッセージ
が出るときがあります。
 このダイアログとメッセージはどんなときに出るのでしょうか。検索対象語がカ
レントフォルダ内にあるときは常に問題ないようです。

       では, (^^)/~

[ ]
RE:07474 ExecAt でデッドロックNo.07475
秀まるお さん 03/11/29 22:19
 
 ExecAtは、デッドロックを検出するために、SendMessageTimeoutという関数を
使ってまして、タイムアウト時間が10秒になってます。

 メッセージを送った先のウィンドウ(というか、スレッド)が、10秒以内に
応答しなければ、「デッドロック」のエラーを表示してしまいます。

 とりあえず、タイムアウト時間をもっと長くすれば回避できると思いますけど、
それはそれで、本当にデッドロックした時のエラー検出に大変待たされることに
なります。

 鶴亀内部でのスレッド間通信では、実はSendMessageTimeoutよりもはるかに面
倒な処理をしてまして、スレッドのデッドロックも起きないように、さらには処
理に非常に時間がかかった場合でもデッドロックと解釈しないように処理してい
ます。

 ExecAtでもそこまで面倒な同期処理をしてやる手もあるにはありますが…。出
来れば検索のような時間のかかる処理は、setactivehidemaruでウィンドウを切
り替えて実行して欲しい気もします。

 現状のExecAtとは別に、高度なスレッド間同期を行うExecAt2関数でも追加で
きるか検討してみます。

[ ]
RE:07475 ExecAt でデッドロックNo.07476
秀まるお さん 03/11/29 23:21
 
 ExecAtMainという関数を追加しました。それでなんとかなりました。

   #n = dllfunc("ExecAt", #wnd, .... )

   となっているのを、

   #n = dllfunc("ExecAtMain", ... )

 にすればいいです。

 あと、ExecAtのタイムアウト時間が5秒になっていたので、それを20秒にし
ました。さらに、タイムアウトした時のエラーメッセージも、「デッドロックし
たか、または処理が終わるのを待ちきれませんでした」に変更しました。

 ExecAtMainの動作テストをしていたら、「全アカウント」を対象に検索しても、
アカウントグループがあるとそこで検索が止まってしまうバグも見つかりました。
それも直しました。

[ ]
RE:07476 ExecAt でデッドロックNo.07477
山紫水明 さん 03/11/30 10:02
 
 秀まるおさん,こんにちは。

》 ExecAtMainという関数を追加しました。それでなんとかなりました。

 動作確認しました。いつもながらの迅速な対応感服いたします。

》   #n = dllfunc("ExecAt", #wnd, .... )

》   となっているのを、

》   #n = dllfunc("ExecAtMain", ... )

》 にすればいいです。

 ということとは,今後はメインウィンドウを呼び出すときは,すべてこの1行
で処理できるので,"ExecAt" 関数を用いる必要はなくなったということです
ね。

     では, (^^)/~
                                        山紫水明

[ ]