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