4

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?

5
  • 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.
    – user1968
    Nov 15, 2014 at 13:42
  • 1
    Hm, interesting. Presumably sleep-for counts as idle. What about if garbage collection occurs? Nov 15, 2014 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.
    – user1968
    Nov 15, 2014 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."
    – user1968
    Nov 15, 2014 at 14:23
  • @JonO. would you like to make your comments an answer? Nov 15, 2014 at 16:53

1 Answer 1

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 and acknowledge that you have read and understand our privacy policy and code of conduct.

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