[Date Prev][Date Next][Thread Prev][][Date Index][Thread Index]

wait asynchronous process (was: Error process-filter/sentinel whenexec w3m-delete-buffer)



>> On Sat, 08 Nov 2003 11:48:31 +0900
>> 「土」== tsuchiya@pine.kuee.kyoto-u.ac.jp (TSUCHIYA Masatoshi) said as follows:

土> どうやら,w3m-process-with-wait-handler で非同期プロセスの終了待ち
土> をしている時,データの末尾が挿入されるよりも前に,終了したと判断し
土> てしまっていたようです.

この問題は,予想以上に対処が難しいことが判明しました.と言うのは,

土> ただ,ここら辺の処理がうまく動くかどうかは,かなり環境に依存するよ
土> うなので,更にテストが必要です.

私の予想以上に環境依存なので,びっくりしました.手元で試験できる組合わ
せでの結果を末尾に添付しましたが,全て失敗している XEmacs21.2.6@Solaris
は論外としても,確実に成功する終了待ち条件がまだ見つかっていません.

ここまでの結果を見る限りでは,Emacs21 は accept-process-output を使い,
それ以外は sit-for を使うようにすれば,なんとかなりそうですが….

土> Meadow / XEmacs / Mule などの他の Emacsen を利用されている方,また,
土> Mac OS X や OS/2 などの他の OS を利用されている方の追試をお願いし
土> ます.

添付の検証用コードで追試を重ねてお願いします.また,UNIX 系でも,環境
によって結果が変わってくるようですから,BSD を使っている人の動作レポー
トも必要です.実験対象とするファイルは async-test の中の定数を適当に変
更してください.

宜しくお願いします.

-- 
土屋 雅稔 ( TSUCHIYA Masatoshi )

(or (fboundp 'with-current-buffer)
    (progn
      (defmacro with-current-buffer (buffer &rest body)
	"Execute the forms in BODY with BUFFER as the current buffer."
	(let ((orig-buffer (make-symbol "orig-buffer")))
	  (` (let (((, orig-buffer) (current-buffer)))
	       (unwind-protect
		   (progn
		     (set-buffer (, buffer))
		     (,@ body))
		 (set-buffer (, orig-buffer)))))))
      (put 'with-current-buffer 'edebug-form-spec '(form body))
      (put 'with-current-buffer 'lisp-indent-function 1)))

(or (fboundp 'with-temp-buffer)
    (progn
      (defmacro with-temp-buffer (&rest body)
	"Create a temporary buffer, and evaluate BODY there like `progn'."
	(let ((buffer (make-symbol "temp-buffer")))
	  (` (let (((, buffer) (generate-new-buffer " *temp*")))
	       (unwind-protect
		   (with-current-buffer (, buffer)
					(,@ body))
		 (and (buffer-name (, buffer))
		      (kill-buffer (, buffer))))))))
      (put 'with-temp-buffer 'edebug-form-spec '(body))
      (put 'with-temp-buffer 'lisp-indent-function 0)))

(defmacro async-test (&rest body)
  `(let ((file "/etc/bash_completion")
	 (times 20)
	 (count 0)
	 (success 0))
     (while (<= (setq count (1+ count)) times)
       (if (progn ,@body)
	   (setq success (1+ success))))
     (if (= success times)
	 (message "Success")
       (message "Fail (%d/%d)" success times))))
(put 'async-test 'edebug-form-spec '(body))

;; Emacs21.3@Linux       => Fail (18/20)
;; Emacs20.7@Linux       => Fail (18/20)
;; XEmacs21.4.6@Linux    => Success
;; Mule2.3-19.34@Linux   => Fail (16/20)
;; Emacs21.2@Solaris     => Success
;; Emacs20.7@Solaris     => Success
;; XEmacs21.2.9@Solaris  => Endless Loop
;; Mule2.3-19.34@Solaris => Success
(async-test
 (with-temp-buffer
   (let* ((coding-system-for-read 'binary)
	  (proc (start-process "cat" (current-buffer) "cat" file)))
     (set-process-sentinel proc 'ignore)
     (while (eq 'run (process-status proc))
       (accept-process-output nil 0 200))
     (= (buffer-size) (nth 7 (file-attributes file))))))

;; Emacs21.3@Linux       => Success
;; Emacs20.7@Linux       => Success
;; XEmacs21.4.6@Linux    => Endless Loop
;; Mule2.3-19.34@Linux   => Fail (19/20)
;; Emacs21.2@Solaris     => Success
;; Emacs20.7@Solaris     => Endless Loop
;; XEmacs21.2.9@Solaris  => Endless Loop
;; Mule2.3-19.34@Solaris => Success
(async-test
 (with-temp-buffer
   (let* ((coding-system-for-read 'binary)
	  (proc (start-process "cat" (current-buffer) "cat" file)))
     (set-process-sentinel proc 'ignore)
     (while (or (accept-process-output proc 0 0)
		(eq 'run (process-status proc))))
     (= (buffer-size) (nth 7 (file-attributes file))))))

;; Emacs21.3@Linux       => Success
;; Emacs20.7@Linux       => Fail (19/20)
;; XEmacs21.4.6@Linux    => Success
;; Mule2.3-19.34@Linux   => Success
;; Emacs21.2@Solaris     => Success
;; Emacs20.7@Solaris     => Success
;; XEmacs21.2.9@Solaris  => Endless Loop
;; Mule2.3-19.34@Solaris => Success
(async-test
 (with-temp-buffer
   (let* ((coding-system-for-read 'binary)
	  (proc (start-process "cat" (current-buffer) "cat" file)))
     (set-process-sentinel proc 'ignore)
     (while (or (accept-process-output proc 0 200)
		(eq 'run (process-status proc))))
     (= (buffer-size) (nth 7 (file-attributes file))))))

;; Emacs21.3@Linux       => Fail(19/20)
;; Emacs20.7@Linux       => Success
;; XEmacs21.4.6@Linux    => Success
;; Mule2.3-19.34@Linux   => Success
;; Emacs21.2@Solaris     => Success (too slow!)
;; Emacs20.7@Solaris     => Success
;; XEmacs21.2.9@Solaris  => Endless Loop
;; Mule2.3-19.34@Solaris => Success
(async-test
 (with-temp-buffer
   (let* ((coding-system-for-read 'binary)
	  (proc (start-process "cat" (current-buffer) "cat" file)))
     (set-process-sentinel proc 'ignore)
     (while (or (not (sit-for 0.1))
		(eq 'run (process-status proc))))
     (= (buffer-size) (nth 7 (file-attributes file))))))