branch: externals/drepl
commit f7baf76921627a0c267ebfa1d0bb49eaed014e5e
Author: Augusto Stoffel <arstof...@gmail.com>
Commit: Augusto Stoffel <arstof...@gmail.com>

    Fix race condition involving checkinput followed by eval
---
 drepl-lua.lua |  4 ----
 drepl.el      | 16 +++++++---------
 2 files changed, 7 insertions(+), 13 deletions(-)

diff --git a/drepl-lua.lua b/drepl-lua.lua
index f98e725a44..22bd1a8d0c 100644
--- a/drepl-lua.lua
+++ b/drepl-lua.lua
@@ -64,10 +64,6 @@ end
 function drepl:drepl_checkinput(args)
   local _, err = self:compilechunk(args.code)
   local cont = err and self:detectcontinue(err)
-  -- FIXME: the following avoids a race condition, but we should
-  -- prescribe in the protocol which methods switch from ready to
-  -- other states.
-  sendmsg{op="status", status="ready"}
   sendmsg{
     id=args.id,
     status=not err and "complete" or cont and "incomplete" or "invalid",
diff --git a/drepl.el b/drepl.el
index 9c05ef332b..614f64ac13 100644
--- a/drepl.el
+++ b/drepl.el
@@ -214,12 +214,11 @@ and this function returns the response data directly."
                result))
     (let* ((id (cl-incf (drepl--last-id repl)))
            (data `(:id ,id :op ,(symbol-name op) ,@args)))
-      (push (cons id callback) (if-let ((reqs (drepl--callbacks repl)))
-                                   (cdr reqs)
-                                 (drepl--callbacks repl)))
+      (push (cons id callback) (drepl--callbacks repl))
       (if (eq 'ready (drepl--status repl))
           (drepl--send-request repl data)
-        (push (cons id data) (drepl--pending repl)))
+        ;; Add a pending request to the end of the queue.
+        (setf (drepl--pending repl) (nconc (drepl--pending repl) (list data))))
       id)))
 
 (defun drepl--osc-handler (_cmd text)
@@ -239,11 +238,10 @@ TEXT is a still unparsed message received from the 
interpreter."
                                nil))
                      (apply-partially #'drepl--handle-notification
                                       repl))))
-    (when-let ((nextreq (and (eq (drepl--status repl) 'ready)
-                             (pop (drepl--pending repl)))))
-      (drepl--send-request repl nextreq))
-    (when callback
-      (funcall callback data))))
+    (when callback (funcall callback data))
+    (when-let ((next (and (eq (drepl--status repl) 'ready)
+                          (pop (drepl--pending repl)))))
+      (drepl--send-request repl next))))
 
 (cl-defgeneric drepl--handle-notification (repl data)
   "Method called when REPL sends a notification.

Reply via email to