Issue #24 resolved

(Part17, 814) $XYZZY/xyzzy.ini が読み込まれない場合がある

Anonymous created an issue

== 再現方法 ==

multiframe_0_2_3_5.zip を展開する

コマンドラインで展開した xyzzy.exe のあるディレクトリまで移動する

下記のコマンドを実行

\ {{{> start /wait .\xyzzy.exe -no-init-file}}}

起動した xyzzy のメニューの「ツール(T)>共通設定...(C)」を選択し、背景色を「赤」に変更し、xyzzy を終了

下記のコマンドを実行

\ {{{> copy .\usr\%USERNAME%\wxp\xyzzy.ini .}}} \ {{{> start /wait .\xyzzy.exe -no-init-file}}}

起動した xyzzy のメニューの「ツール(T)>共通設定...(C)」を選択し、背景色を「白」に変更し、xyzzy を終了

下記のコマンドを実行

\ {{{> .\xyzzy.exe -no-init-file}}}

scratch で下記のコマンドの実行を繰り返す

\ {{{(progn (call-process "xyzzy.exe -no-init-file") (kill-xyzzy))}}}

== 期待する動作 == * 背景が「白」の状態の xyzzy が起動する

== 実際の動作 == * 背景が「赤」の状態の xyzzy が起動する

== 再現バージョン == * 0.2.3.5

== 備考 == Part17, 814 : http://toro.2ch.net/test/read.cgi/win/1303662374/814 {{{ exeと同じ場所にiniを置いた状態で (call-process "xyzzy.exe") (kill-xyzzy) みたいに起動と終了を同時にやるとたまに上記のiniは無視されて XYZZYCONFIGPATHのiniをつかうことがある }}}

頻度について (「赤」背景の発生数 / 試行回数)\ Part17, 838 : http://toro.2ch.net/test/read.cgi/win/1303662374/838 {{{ 何も追加していないxyzzy 1/100 7/100 1/100 0/100 5/100 6/100 1/100 0/100 0/100 0/100 21/1000

実際に使っているxyzzy 4/100 12/100 8/100 12/100 8/100 44/500 }}}

Comments (9)

  1. Anonymous

    原因と対処の検討

    原因は?

    call-process 実行元の xyzzy.exe の kill-xyzzy 実行時、 toplev.cc:toplevel_wndproc() の WM_DESTROY から始まる処理中、 environ.cc:environ::save_geometry() において $XYZZY/xyzzy.ini への書き込みが行われます。

    この書き込み中に、新しい xyzzy.exe の init.cc:FileExists() が $XYZZY/xyzzy.ini に 対して呼び出されると、CreateFile() が失敗し、FileExists() は false を返します。

    結果として、$XYZZY/xyzzy.ini が読み込まれません。

    現象の解消実験

    あまり良いものではないですが、現象を解消するパッチを作成しました:

    814 の方に試験してもらい、100回の試行で「赤」背景の状態が再現しないことを確認済みです:

    コードの検討

    上記のコードは、WM_DESTROY 時の $XYZZY/xyzzy.ini への書き込みを抑制することを目的とした改変を行っています。

    • environ::save_geometry() の write_conf() について、キャッシュ動作を行うように変更
    • environ::save_geometry() を lisp 側から呼び出せるように Fsave_user_config_geometry() を追加

    この方向でコードを変更する場合の検討点としては、以下が挙げられます:

    • environ::save_geometry() だけ、別の write_conf() を持つ形で良いのか?
    • conf.cc:write_conf() のレベルで変更したほうが良いのか?
    • save-user-config-geometry のような具体的な名前ではなく、prepare-for-kill-xyzzy のようなものを用意したほうが将来の拡張に備えやすいのでは?

    call-process :wait n との整合性を高める

    別の実装方法として、call-process の wait に数値を与えた場合、 process.cc:Fcall_process() 内で実行される WaitForInputIdle() が xyzzy.exe に対しても期待通りに動作するような改変もあり得ます。

    現状 xyzzy は起動後にメインループのメッセージハンドラが動作する前に toplev.cc:start_quit_thread() が呼び出され、 toplev.cc:quit_thread_entry() が持つメッセージハンドラが動作するため、 実際のアイドルループに入る前に WM_ENTERIDLE が発行され、WaitForInputIdle() の動作が完了しています。

    これは本来の WaitForInputIdle() の期待する動作とは異なります。 そこで、quit_thread_entry() の動作を遅らせるように、以下の処理を追加します

    //src/init.cc
    +	HANDLE startupEvent = NULL;
    
    	int PASCAL
    	WinMain (HINSTANCE hinst, HINSTANCE, LPSTR, int cmdshow)
    	{
    +	  startupEvent = CreateEvent(0, 0, 0, 0);
    	  int ole_initialized = 0;
    	  if (init_root_app (hinst, cmdshow, ole_initialized))
    	    {
    +	      SetEvent(startupEvent);
    
    //src/toplev.cc
    	static u_int __stdcall
    	quit_thread_entry (void *p)
    	{
    	...
    +	  extern HANDLE startupEvent;
    +	  WaitForSingleObject(startupEvent, 30000);  // INFINITE でも良いか?
    	  RegisterHotKey (0, HK_BREAK, MOD_CONTROL, VK_CANCEL);
    	  SetTimer (0, 0, 1000, 0);
    

    この処理を追加することで、WaitForInputIdle() は xyzzy.exe の初期化完了を待ってから、 動作を終了します。

    ただし、この処理のみだと前の xyzzy のウィンドウ位置等が保存されないまま新しい xyzzy が実行されるので、 前述の Fsave_user_config_geometry() は同様に追加します。

    この場合の再起動的な処理の記述方法は以下のようになります

    (progn (save-user-config-geometry)
           (call-process "xyzzy.exe" :wait 10)
           (kill-xyzzy))
    
  2. mumurik repo owner

    2chにコメント書いた後にこれ見てみた。うーん、cacheなんてのがいるのか。 前回保存からdirtyになってないってのを認識しないといけないって事だね。 名前はprepare-forなんちゃらの方がいいかもなぁ。

    idleになる前にidleになるなやゴルァ!ってのもまぁそうかもしれんが、別に適当にsleepしろよ、でいい気もする。 一番バグが少なさそうな手段を勝手に選んでくれていいよ。

  3. Anonymous

    名称を prepare-for-kill-xyzzy に変更して、プロセスアイドル待ちにしたものをテスト用に上げました

    キャッシュ/dirty式に対して、アイドル待ちのほうが良いと思う理由は

    • xyzzy.ini への書き込み量が増えたときでも楽 (キャッシュだとアレコレ追記しないといけない)

    という一点だけです。

    あと .xyzzy の読み込み時の C-g での abort が従来どおり効くことは確認したので、 この変更による使用上の不利益も無いと思っています。

  4. mumurik repo owner

    一応私が持っときますが、リリースしたら確認して閉じてくれると嬉しい (まぁ確認してくれれば閉じるのは私がやってもいいです)

  5. xyzzy_17_638

    以下の確認をしてもらったので、解消とします。

    Part17, 981

    981 :814:2012/03/31(土) 11:03:37.57 ID:
    >>940 
    遅くなりましたが今回も100回のテストをしました 
    問題なく動作しています 
    
  6. Log in to comment