branch: externals/phpinspect
commit 857fcf14fe08c809a5da2ae9d7c365ae4c0a0109
Author: Hugo Thunnissen <de...@hugot.nl>
Commit: Hugo Thunnissen <de...@hugot.nl>

    Use condition variables to wait for shadow synchronization
---
 phpinspect-buffer.el | 46 +++++++++++++++++++++++++++++++++-------------
 phpinspect-eldoc.el  |  2 +-
 phpinspect-thread.el | 18 ++++++++++++------
 3 files changed, 46 insertions(+), 20 deletions(-)

diff --git a/phpinspect-buffer.el b/phpinspect-buffer.el
index 452f65280b..97e2ab3e14 100644
--- a/phpinspect-buffer.el
+++ b/phpinspect-buffer.el
@@ -616,6 +616,7 @@ continuing execution."
   ;; for a shadow thread, which would be blocked while waiting for the
   ;; autoloader regardless.
   (phpinspect-project-await-autoload (phpinspect-buffer-project buffer))
+  (phpi-shadow-enqueue-task (phpinspect-buffer-shadow buffer) 
'update-project-index)
   (phpi-shadow-await-index-synced (phpinspect-buffer-shadow buffer) t))
 
 (defun phpinspect-buffer-parse-map (buffer)
@@ -746,9 +747,9 @@ If provided, PROJECT must be an instance of 
`phpinspect-project'."
   (queue nil :type phpinspect--queue)
   (thread nil :type thread)
   (id nil :type integer)
-  (-last-change nil)
-  (-synced-change nil)
-  (-indexed-change nil)
+  (-last-change (phpi-make-condition))
+  (-synced-change (phpi-make-condition))
+  (-indexed-change (phpi-make-condition))
   (-deletions nil :type list)
   (-additions (make-hash-table :test #'eq) :type hash-table))
 
@@ -830,7 +831,7 @@ indexation"))
       (phpi-shadow--set-buffer-map
        shadow (phpinspect-pctx-bmap pctx) (phpinspect-pctx-previous-bmap pctx))
 
-      (setf (phpi-shadow--synced-change shadow) change))))
+      (setf (phpi-condition-value (phpi-shadow--synced-change shadow)) 
change))))
 
 (defun phpi-shadow-parse-fresh (shadow)
   (with-current-buffer (phpi-shadow-buffer shadow)
@@ -851,7 +852,7 @@ indexation"))
         (phpi-shadow--set-buffer-map
          shadow (phpinspect-pctx-bmap pctx) nil)
 
-        (setf (phpi-shadow--synced-change shadow) 'parse-fresh)))))
+        (setf (phpi-condition-value (phpi-shadow--synced-change shadow)) 
'parse-fresh)))))
 
 (defun phpinspect-visit-shadow-buffer (buffer)
   (interactive (list (or phpinspect-current-buffer
@@ -896,13 +897,32 @@ indexation"))
       (thread-yield))))
 
 (defun phpi-shadow-synced-p (shadow)
-  (eq (phpi-shadow--synced-change shadow) (phpi-shadow--last-change shadow)))
+  (eq (phpi-condition-value (phpi-shadow--synced-change shadow))
+      (phpi-condition-value (phpi-shadow--last-change shadow))))
 
 (defun phpi-shadow-await-synced (shadow &optional allow-interrupt)
-  (phpi-shadow-await-predicate shadow #'phpi-shadow-synced-p allow-interrupt))
+  (phpi-shadow-assert-live-p shadow)
+  (unless (phpi-shadow-is-me-p shadow)
+    (phpi-condition-wait (phpi-shadow--synced-change shadow)
+                         (lambda (change)
+                           (and change
+                                (eq change
+                                    (phpi-condition-value 
(phpi-shadow--last-change shadow))))))))
+  ;; (phpi-shadow-await-predicate shadow #'phpi-shadow-synced-p 
allow-interrupt))
 
 (defun phpi-shadow-await-index-synced (shadow &optional allow-interrupt)
-  (phpi-shadow-await-predicate shadow #'phpi-shadow-index-synced-p 
allow-interrupt))
+  (phpi-shadow-assert-live-p shadow)
+
+  ;; First wait for last change to be synced
+  (phpi-shadow-await-synced shadow)
+
+  ;; Now wait for last change to be indexed
+  (unless (phpi-shadow-is-me-p shadow)
+    (phpi-condition-wait (phpi-shadow--indexed-change shadow)
+                         (lambda (change)
+                           (and change
+                                (eq change
+                                    (phpi-condition-value 
(phpi-shadow--synced-change shadow))))))))
 
 (defun phpi--handle-use-trait-deletion (buffer deletion)
   (when-let ((class (seq-find (phpinspect-meta-token-predicate 
#'phpinspect-class-p)
@@ -1034,7 +1054,7 @@ SHADOW should be an instance of `phpinspect-shadow'."
    reindex-table)))
 
 (defun phpi-shadow-update-project-index (shadow)
-  (let ((change (phpi-shadow--last-change shadow))
+  (let ((change (phpi-condition-value (phpi-shadow--synced-change shadow)))
         (ctx (phpi-make-sidc)))
     (when (phpinspect-buffer-project (phpi-shadow-origin shadow))
       (phpi-shadow-process-deletions shadow ctx)
@@ -1043,7 +1063,7 @@ SHADOW should be an instance of `phpinspect-shadow'."
       (when (phpi-sidc-imports-changed ctx)
         (phpi-process-reindex-after-import (phpi-shadow-origin shadow)))
 
-      (setf (phpi-shadow--indexed-change shadow) change))))
+      (setf (phpi-condition-value (phpi-shadow--indexed-change shadow)) 
change))))
 
 (defun phpi-shadow--handle-job (shadow job)
   (phpi-progn
@@ -1055,8 +1075,8 @@ SHADOW should be an instance of `phpinspect-shadow'."
 
 (defun phpi-shadow-index-synced-p (shadow)
   (and (phpi-shadow-synced-p shadow)
-       (eq (phpi-shadow--synced-change shadow)
-           (phpi-shadow--indexed-change shadow))))
+       (eq (phpi-condition-value (phpi-shadow--synced-change shadow))
+           (phpi-condition-value (phpi-shadow--indexed-change shadow)))))
 
 (defun phpi-shadow-make-job-queue (shadow)
   ;; Make sure that the thread uses shadow buffer as its current buffer. This
@@ -1094,7 +1114,7 @@ SHADOW should be an instance of `phpinspect-shadow'."
 
 (defun phpi-shadow-enqueue-task (shadow task)
   (when (or (phpinspect-change-p task) (eq 'parse-fresh task))
-    (setf (phpi-shadow--last-change shadow) task))
+    (setf (phpi-condition-value (phpi-shadow--last-change shadow)) task))
 
   (if phpinspect--shadow-run-sync
       (phpi-shadow--handle-job shadow task)
diff --git a/phpinspect-eldoc.el b/phpinspect-eldoc.el
index 35307e66c0..5de8576cac 100644
--- a/phpinspect-eldoc.el
+++ b/phpinspect-eldoc.el
@@ -304,7 +304,7 @@ TODO:
 "
   (when phpinspect-current-buffer
     (phpi-run-threaded "PHPInspect Eldoc"
-      (while-no-input
+      (While-no-input
         (let ((result (phpinspect--eldoc-function-sync)))
           (funcall callback result))))
 
diff --git a/phpinspect-thread.el b/phpinspect-thread.el
index fdfac84ad3..d011e431e9 100644
--- a/phpinspect-thread.el
+++ b/phpinspect-thread.el
@@ -51,16 +51,21 @@
   (setf (phpi-condition--value condition) value)
   (phpi-condition-notify condition))
 
-(defun phpi-condition-wait (condition)
+(defun phpi-condition-wait (condition &optional predicate)
   (let ((mx (phpi-condition--mx condition))
         (condvar (phpi-condition--condvar condition))
         result)
 
-    (while (not (setq result (phpi-condition--value condition)))
-      (with-mutex mx
-        (condition-wait condvar)))
+    (if predicate
+        (while (not (funcall predicate (setq result (phpi-condition--value 
condition))))
+          (with-mutex mx
+            (condition-wait condvar)))
+
+      (let ((start-val (phpi-condition--value condition)))
+        (while (eq start-val (setq result (phpi-condition--value condition)))
+          (with-mutex mx
+            (condition-wait condvar)))))
 
-    (setf (phpi-condition--value condition) nil)
     result))
 
 (defun phpi-make-condition (&optional value)
@@ -167,7 +172,8 @@ If current thread is the main thread, this function does 
nothing."
                           ;; If job queue end is signaled, exit after queue has
                           ;; been fully depleted.
                           (setq ended t)
-                          (unless (phpinspect-queue-first queue)
+                          (if (phpinspect-queue-first queue)
+                              (setq ended nil)
                             (throw 'phpi--break nil)))))
 
                     (if ended

Reply via email to