anchor.diff:                   ((and timeout-time (> (now) timeout-time))
                     (return (values nil :timeout)))
                    (t
  -                  (condition-wait cv lock decay)))))))
  +                  (let* ((schedule-time (event-schedule-time queue))
  +                         (decay (compute-decay timeout-time schedule-time)))
  +                    (condition-wait cv lock decay))))))))
   
   (defmethod event-queue-append ((queue concurrent-event-queue) item)
  -  (with-recursive-lock-held ((event-queue-lock queue))
  +  (with-lock-held ((event-queue-lock queue))
       (call-next-method)
       (condition-notify (event-queue-processes queue))))
   
   (defmethod event-queue-prepend ((queue concurrent-event-queue) item)
  -  (with-recursive-lock-held ((event-queue-lock queue))
  +  (with-lock-held ((event-queue-lock queue))
       (call-next-method)
       (condition-notify (event-queue-processes queue))))
   
   (defmethod event-queue-peek ((queue concurrent-event-queue))
     (do-port-force-output queue)
  -  (with-recursive-lock-held ((event-queue-lock queue))
  -    (check-schedule queue)
  +  (check-schedule queue)
  +  (with-lock-held ((event-queue-lock queue))
       (first (event-queue-head queue))))
   
   (defmethod event-queue-peek-if (predicate (queue concurrent-event-queue))
     (do-port-force-output queue)
  -  (with-recursive-lock-held ((event-queue-lock queue))
  +  (check-schedule queue)
  +  (with-lock-held ((event-queue-lock queue))
       (find-if predicate (event-queue-head queue))))
  -
  -(defmethod event-queue-listen ((queue concurrent-event-queue))
  -  (do-port-force-output queue)
  -  (check-schedule queue)
  -  (not (null (event-queue-head queue))))
   
   (defmethod event-queue-listen-or-wait ((queue concurrent-event-queue)
                                          &key timeout wait-function)
  
positive.code: (defmethod event-queue-peek ((queue simple-event-queue))
    (do-port-force-output queue)
    (check-schedule queue)
    (or (first (event-queue-head queue))
        (when (process-next-event (event-queue-port queue) :timeout 0)
          (first (event-queue-head queue)))))
  
  (defmethod event-queue-peek-if (predicate (queue simple-event-queue))
    (do-port-force-output queue)
    ;; Slurp as many elements as available.
    (loop until (null (process-next-event (event-queue-port queue) :timeout 0)))
    ;; Check-schedule may append scheduled event in a queue.
    (check-schedule queue)
    (find-if predicate (event-queue-head queue)))
  
  (defmethod event-queue-listen-or-wait ((queue simple-event-queue)
                                         &key timeout wait-function)
    (do-port-force-output queue)
    (let ((port (event-queue-port queue))
          (timeout-time (and timeout (+ timeout (now)))))
      ;; timeout-time may be past-due already but we may have an event waiting to be
      ;; processed for some time. Do preemptive check. -- jd 2018-12-30
      (process-next-event port :timeout 0)
      (loop
         as decay = (compute-decay timeout-time (event-schedule-time queue))
         do
           (when decay (maxf decay 0))
           (check-schedule queue)
           (cond ((event-queue-head queue)
                  (return t))
                 ((maybe-funcall wait-function)
                  (return (values nil :wait-function)))
                 ((and timeout-time (> (now) timeout-time))
                  (return (values nil :timeout)))
                 (T
                  (process-next-event port :timeout decay :wait-function wait-function))))))
  
  (defmethod event-queue-listen ((queue simple-event-queue))
    (event-queue-listen-or-wait queue :timeout 0))
  
  
  (defclass concurrent-event-queue (simple-event-queue)
    ((lock :initform (make-recursive-lock "event queue")
           :reader event-queue-lock)
     (processes
           :initform (make-condition-variable)
           :accessor event-queue-processes
           :documentation "Condition variable for waiting processes")))
  
  (defmethod check-schedule :around ((queue concurrent-event-queue))
    (with-recursive-lock-held ((event-queue-lock queue))
      (call-next-method)))
  
  (defmethod schedule-event-queue :around ((queue concurrent-event-queue) event delay)
    (with-recursive-lock-held ((event-queue-lock queue))
      (call-next-method)))
  
  (defmethod event-queue-read ((queue concurrent-event-queue))
    (do-port-force-output queue)
    (let ((lock (event-queue-lock queue))
          (cv (event-queue-processes queue)))
      (loop
         as decay = (compute-decay nil (event-schedule-time queue))
         do (with-recursive-lock-held (lock)
              (if-let ((result (%event-queue-read queue)))
                (return result)
                (condition-wait cv lock decay))))))
  
  (defmethod event-queue-read-no-hang ((queue concurrent-event-queue))
    (do-port-force-output queue)
    (with-recursive-lock-held ((event-queue-lock queue))
      (%event-queue-read queue)))
  
  ;;; XXX Should we do something with the wait function? I suspect that
  ;;; it's not compatible with the brave new world of native threads.
  
  (defmethod event-queue-read-with-timeout ((queue concurrent-event-queue)
                                            timeout wait-function)
  
negative.code:      with lock = (event-queue-lock queue)
       with cv = (event-queue-processes queue)
       with timeout-time = (and timeout (+ timeout (now)))
       do
         (check-schedule queue)
         (with-lock-held (lock)
           (cond ((event-queue-head queue)
                  (return t))
                 ((maybe-funcall wait-function)
                  (return (values nil :wait-function)))
                 ((and timeout-time (> (now) timeout-time))
                  (return (values nil :timeout)))
                 (wait-function
                  ;; We CLAMP decay when wait-function is present to
                  ;; ensure that we don't get stuck until next event
                  ;; arrives (or the timeout happens). It is busy wait
                  ;; with a lousy grain. -- jd 2019-06-06
                  (if-let ((decay (compute-decay timeout-time
                                                 (event-schedule-time queue))))
                    (condition-wait cv lock (min 0.01 decay))
                    (condition-wait cv lock 0.01)))
                 (t
                  (let ((decay (compute-decay timeout-time
                                              (event-schedule-time queue))))
                    (condition-wait cv lock decay)))))))
  
  
  