5

I want to call a command asynchronously, and define a function that handles output from that command. I don't want to simply write output to a buffer.

According to the Elisp info (36.9.2 Process Filter Functions) I need to set a process filter function. I tried this:

(defun my-echo-filter (proc string)
  (message "proc: %s string: %s" proc string))

(let ((my-proc (start-file-process "foo" nil "date")))
  (set-process-filter my-proc #'my-echo-filter)) ; writes the time to *Messages*

However, this makes me nervous. I'm starting the process first, and only afterwards am I attaching the process filter.

If I do anything between creating the process and attaching the process filter, I can miss output.

(let ((my-proc (start-file-process "foo" nil "date")))
  (sleep-for 2)
  (set-process-filter my-proc #'my-echo-filter)) ; Does not write the time!

How do I create a process and ensure that my process filter doesn't miss anything?

  • 2
    I'm not an expert, but I think this is a non-issue. Emacs is single-threaded, and only processes output from subprocesses when idle. There's no time in between calling start-file-process and set-process-filter when process output could arrive behind your back (as it were). You would have to call sit-for or accept-process-output for that to happen. – Jon O. Nov 15 '14 at 13:42
  • 1
    Hm, interesting. Presumably sleep-for counts as idle. What about if garbage collection occurs? – Wilfred Hughes Nov 15 '14 at 14:13
  • It seems very unlikely to me that GC would trigger anything related to subprocesses -- AFAIK there's very little that can safely be handled during GC -- but you would have to ask someone more expert for a definitive answer. – Jon O. Nov 15 '14 at 14:22
  • 1
    BTW, the relevant line is in (elisp) Accepting Output: "Output from asynchronous subprocesses normally arrives only while Emacs is waiting for some sort of external event, such as elapsed time or terminal input." – Jon O. Nov 15 '14 at 14:23
  • @JonO. would you like to make your comments an answer? – Wilfred Hughes Nov 15 '14 at 16:53
7

As I understand it, this is a non-issue. Emacs is single-threaded, and only processes output from subprocesses when idle. Therefore, there is no time between calling start-file-process and set-process-filter when process output could arrive without being handled.

The info page (elisp) Accepting Output states:

Output from asynchronous subprocesses normally arrives only while Emacs is waiting for some sort of external event, such as elapsed time or terminal input.

For this to become a problem, you would have to separate creating the process and setting the filter function with a call to sit-for, accept-process-output, or some other command that involves user interaction via the event loop.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.