[Message Prev][Message Next][Thread Prev][Thread Next][Message Index][Thread Index]
Re: [MD:4310] Meadow のデッドロック?
- X-ml-count: 4319
- Subject: Re: [MD:4310] Meadow のデッドロック?
- From: MIYOSHI Masanori <miyoshi@xxxxxxxxxxxxxxxx>
- Date: Wed, 02 Apr 2003 19:53:24 +0900
- User-agent: Wanderlust/2.11.1 (Wonderwall) EMIKO/1.14.1 (Choanoflagellata) LIMIT/1.14.7 (Fujiidera) APEL/10.4 Emacs/21.1 (i386-msvc-nt5.1.2600) MULE/5.0 (SAKAKI) Meadow/1.99 Alpha6-dev (IKADUCHI)
>>>>> [meadow-develop : No.4317] にて
>>>>> "三好" = 私は書きました:
himi> > 対処療法になりますが、下記の patch のように message を使わずに
himi> > Imm 関連の関数を直接呼び出すことで、この問題は回避できます。
himi> > commit しても構わないでしょうかね?
himi> これはだめ。Imm APIの仕様上、thread safeでないので。
三好> 了解しました。
三好> このために、メインスレッドで実行される primitive function では、
三好> Imm API をメッセージで呼び出しているのですね。
原因と対策を整理して考えてみました。
なお、この現象は、圭一さんの報告 [MD:4167] の現象と同じです。
(1) デッドロックの原因
o メインスレッド:Fset_window_configuration()@window.c にて
W32_BLOCK_INPUT が呼ばれて、他のスレッドをブロックする。
o メッセージスレッド:W32_BLOCK_INPUT が呼ばれると、UNBLOCK され
るまで待機状態になる。
o メインスレッド:Fselect_window() -> Ffep_get_mode() が呼ばれる。
o メインスレッド:Ffep_get_mode() では、IME のモードを取得するた
めに、メッセージスレッドにメッセージ送るが、メッセージスレッド
は待機状態にあるため、応答は得られない。
→メッセージスレッドは応答待ち、メッセージスレッドは待機状態のま
まになり、デッドロック発生。
これに限らず、クリティカルセクション(W32_BLOCK_INPUT と
W32_UNBLOCK_INPUT の間)にて、メッセージが使われると、デッドロック
に陥る可能性があります。
(2) 対処方法
クリティカルセクション内では、メッセージスレッドが待機状態に入る
可能性があるので、メッセージを送った後で応答を待つ処理は避けるべ
きです。
対処方法としては、次のようなものが考えられます。
(a) メッセージを使う処理をクリティカルセクション外に追い出す
(a-1) クリティカルセクションの範囲を必要最小限のものに狭める
(a-2) メッセージを使うコードをクリティカルセクション外に移動する
(b) メッセージを使う処理をメッセージを使わないように変更する
(a-1)が一番良い方法だと思いますが、私には無理です。何が必要最小限
かを判断できないからです。
(b)は、Imm API がスレッド・セーフでないので、難しいそうです
([MD:4310])。
となると、私にできるのは (a-2)だけです。
添付の patch のような対応はどうでしょうか?
かなり、無理やりな対応な対応であることは承知しておりますが、現状
のようにデッドロックに陥るよりは、ましだと思います。
--- ./window.c.orig 2003-03-10 23:48:03.000000000 +0900
+++ ./window.c 2003-04-02 19:44:27.000000000 +0900
@@ -4893,6 +4893,18 @@
/* The mouse highlighting code could get screwed up
if it runs during this. */
#ifdef MEADOW
+ /* To prevent deadlock, call select-window-functions() not in
+ Fselect_window() but here. It may cause deadlock to call a
+ function which handles a message in a critical section.
+ */
+ Lisp_Object select_window_functions_orig = Vselect_window_functions;
+
+ if (!NILP (Vselect_window_functions))
+ run_hook_with_args_2 (Qselect_window_functions, selected_window,
+ data->current_window);
+
+ Vselect_window_functions = Qnil;
+
W32_BLOCK_INPUT;
#endif
BLOCK_INPUT;
@@ -5060,6 +5072,9 @@
near the beginning of this function. */
selected_window = Qnil;
Fselect_window (data->current_window);
+ /* restore it now. */
+ Vselect_window_functions = select_window_functions_orig;
+
XBUFFER (XWINDOW (selected_window)->buffer)->last_selected_window
= selected_window;
--
三好 雅則 mailto:miyoshi@xxxxxxxxxxxxxxxx
http://www.boreas.dti.ne.jp/~miyoshi/ (Meadow2 のページ始めました)