Thank you, Alexander.

I was planning to span a new thread but the approach with the queue might be a better fit for us. Do you have the numbers for what will yield better performance - checking input-pending and then thread-yield or directly calling thread-yield?

Ivan

On Sat, May 9, 2020 at 4:09 PM Alexander Miller <alexanderm@web.de> wrote:
[I had to copy the In-Reply-To header from the page source because the
reply-to button
wouldn't set it, so let's hope I'm doing this right.]

Incidentally I have recently been playing around with a similar idea -
to use a worker thread
to split and run long tasks in the background. Here's what I came up
with so far:

(defconst worker-mutex (make-mutex "*WORKER MUTEX*"))
(defconst worker-cond-var (make-condition-variable worker-mutex))
(defvar worker-queue (list))

(setf
  worker
  (make-thread
   (lambda ()
     (while t
       (while worker-queue
         (let* ((work-unit (pop worker-queue))
                (fn (car work-unit))
                (args (cdr work-unit)))
           (apply fn args)
           (thread-yield)))
       (with-mutex worker-mutex
         (condition-wait worker-cond-var))))
   "*WORKER*"))

(setf worker-timer
       (run-with-idle-timer
        1 t (lambda ()
              (when worker-queue
                (with-mutex worker-mutex
                  (condition-notify worker-cond-var))))))

(push (list #'shell-command-to-string "notify-send 'Hello' 'World!'")
worker-queue)
(push (list #'message "Hello %s!" "World") worker-queue)
(push (list #'call-interactively #'treemacs) worker-queue)

Get enough thread-yield or input-pending checks into the work the thread
is doing and
you might just be able to get around blocking the UI despite having
plenty to do.