emacs-devel
[Top][All Lists]
Advanced

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

Re: run-with-timer vs run-with-idle-timer


From: João Távora
Subject: Re: run-with-timer vs run-with-idle-timer
Date: Fri, 11 May 2018 11:39:16 +0100
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/27.0.50 (gnu/linux)

Thien-Thi Nguyen <address@hidden> writes:

> If you can structure whatever ‘catch’es the ‘throw’s to mutate
> state visible to CONDITION, then you can use ‘while CONDITION’.
> If that state is dynamic (e.g., declared w/ ‘defvar’), you can
> can reconfigure the ‘throw’ to simply mutate it directly, and
> eliminate the ‘catch’ part (and still use ‘while CONDITION’).

After thinking a bit about it, you're totally right, and it becomes much
simpler (read below).
>
> I suppose it's a matter of style.

Maybe not, maybe yours is indeed more efficient, since it amounts to
far fewer calls to accept-process-output.

> able to play multiple games simultaneously (i.e., run multiple
> independent child processes), and greedily spinning borks that.

Since from Emacs's perspective we're both blocking, you must mean that
you have less CPU available for the subprocesses, right?

> I'd appreciate seeing a skeleton of the code, because what i
> imagine it to be is probably not exactly what it is.  (I could
> be misunderstanding your description grossly.)

If you haven't yet connected the dots, this is for my new mode eglot.el
from the other thread.  Since it is very new, I think I'm just going to
apply your suggestion (diff below). It works fine and the code becomes
tighter, though it still doesn't solve the original problem that makes
the idle-timer not kick in in the meantime. (Later, I can explain more
about why I need that, and how I'm working around it).

diff --git a/eglot.el b/eglot.el
index aabaf54..d8fa8be 100644
--- a/eglot.el
+++ b/eglot.el
@@ -652,25 +652,20 @@ DEFERRED is passed to `eglot--async-request', which see."
   ;; bad idea, since that might lead to the request never having a
   ;; chance to run, because `eglot--ready-predicates'.
   (when deferred (eglot--signal-textDocument/didChange))
-  (let* ((done (make-symbol "eglot--request-catch-tag"))
-         (res
-          (catch done (eglot--async-request
-                       proc method params
-                       :success-fn (lambda (&rest args)
-                                     (throw done (if (vectorp (car args))
-                                                     (car args) args)))
-                       :error-fn (eglot--lambda
-                                     (&key code message &allow-other-keys)
-                                   (throw done
-                                          `(error ,(format "Oops: %s: %s"
-                                                           code message))))
-                       :timeout-fn (lambda ()
-                                     (throw done '(error "Timed out")))
-                       :deferred deferred)
-                 ;; now spin, baby!
-                 (while t (accept-process-output nil 0.01)))))
-    (when (and (listp res) (eq 'error (car res))) (eglot--error (cadr res)))
-    res))
+  (let (retval)
+    (eglot--async-request
+     proc method params
+     :success-fn (lambda (&rest args)
+                   (setq retval `(done ,(if (vectorp (car args))
+                                            (car args) args))))
+     :error-fn (eglot--lambda (&key code message &allow-other-keys)
+                 (setq retval `(error ,(format "Oops: %s: %s" code message))))
+     :timeout-fn (lambda ()
+                   (setq retval '(error "Timed out")))
+     :deferred deferred)
+    (while (not retval) (accept-process-output nil 30))
+    (when (eq 'error (car retval)) (eglot--error (cadr retval)))
+    (cadr retval)))
 
 (cl-defun eglot--notify (process method params)
   "Notify PROCESS of something, don't expect a reply.e"








reply via email to

[Prev in Thread] Current Thread [Next in Thread]