jwiegley / emacs-async

Simple library for asynchronous processing in Emacs
GNU General Public License v3.0
829 stars 68 forks source link

Running make-thread and async-start Near Each Other Seems to Cause Error #157

Open WammKD opened 1 year ago

WammKD commented 1 year ago

I was just playing around with a simple example and pretty consistently get this error with this particular setup.

I just tried:

(defun example ()
  ""

  (let ((thread (make-thread #'(lambda ()
                                 (message "First call!")))))
    (async-start (lambda ()
                   2)
                 (lambda (_result)
                   (message "Second call!!")))

    5))

Running this function causes the error error in process sentinel: Invalid read syntax: "#". I tried a few different variations (mostly just to try things, see if any different result occurred): using something like a number instead of message, in both places; removing the #' on the lambda; etc. Same result, pretty much all times.

Removing the the thread invocation or process start did restore no error, though; e.g.

(defun example ()
  ""

  (let ((thread t))
    (async-start (lambda ()
                   2)
                 (lambda (_result)
                   (message "Second call!!")))

    5))

and

(defun example ()
  ""

  (let ((thread (make-thread #'(lambda ()
                                 (message "First call!")))))
    5))
Fuco1 commented 1 year ago

It's because the inner lambda will be converted to a closure and it will have the thread object in its scope. Since threads are not readable, it won't work.

You can quote the "worker" lambda to prevent it from being "closure-ified", but that might have other side effects.

This was fixed on Emacs 29, so it will work then. (unless you don't reference the thread variable from the worker lambda which you should not since it makes no sense as that thread won't be in the subprocess).