The aligned goal here is to allow for removing ports, not busy-looping
when there's no ports but something to wait on, and allow for stopping
when nothing is remaining. Accomplishing the latter requires all
of the former.
* 8sync/agenda.scm (<make-port-request>, make-port-remove-request)
(port-remove-request port-remove-request?, stop-on-nothing-to-do):
New variables.
(update-agenda-from-select!): Sleep (via select, currently) when
there's no ports in the queue but we still have things scheduled.
(start-agenda): New comments
port-request-port
port-request-read port-request-write port-request-except
port-request-port
port-request-read port-request-write port-request-except
+ <port-remove-request>
+ make-port-remove-request port-remove-request port-remove-request?
+ port-remove-request-port
+
run-it wrap wrap-apply run run-at run-delay
%run %run-at %run-delay %port-request
run-it wrap wrap-apply run run-at run-delay
%run %run-at %run-delay %port-request
+ stop-on-nothing-to-do
+
%current-agenda
start-agenda agenda-run-once))
%current-agenda
start-agenda agenda-run-once))
(define %current-agenda (make-parameter #f))
(define (update-agenda-from-select! agenda)
(define %current-agenda (make-parameter #f))
(define (update-agenda-from-select! agenda)
- "Potentially (select) on ports specified in agenda, adding items to queue"
+ "Potentially (select) on ports specified in agenda, adding items to queue.
+
+Also handles sleeping when all we have to do is wait on the schedule."
(define (hash-keys hash)
(hash-map->list (lambda (k v) k) hash))
(define (get-wait-time)
(define (hash-keys hash)
(hash-map->list (lambda (k v) k) hash))
(define (get-wait-time)
(has-items? agenda-write-port-map)
(has-items? agenda-except-port-map)))
(has-items? agenda-write-port-map)
(has-items? agenda-except-port-map)))
+ (if (or (ports-to-select?)
+ ;; select doubles as sleep...
+ (not (schedule-empty? (agenda-schedule agenda))))
(hash-remove! (agenda-except-port-map agenda) port)))
(hash-remove! (agenda-except-port-map agenda) port)))
+(define (stop-on-nothing-to-do agenda)
+ (and (q-empty? (agenda-queue agenda))
+ (schedule-empty? (agenda-schedule agenda))
+ (= 0 (hash-count (const #t) (agenda-read-port-map agenda)))
+ (= 0 (hash-count (const #t) (agenda-write-port-map agenda)))
+ (= 0 (hash-count (const #t) (agenda-except-port-map agenda)))))
+
+
(define* (start-agenda agenda
(define* (start-agenda agenda
+ #:key
+ ;; @@: Should we make stop-on-nothing-to-do
+ ;; the default stop-condition?
+ stop-condition
(get-time gettimeofday)
(handle-ports update-agenda-from-select!))
;; TODO: Document fields
(get-time gettimeofday)
(handle-ports update-agenda-from-select!))
;; TODO: Document fields
(agenda-queue agenda))
(loop agenda))))))
(agenda-queue agenda))
(loop agenda))))))
(define (print-error-and-continue key . args)
"Frequently used as pre-unwind-handler for agenda"
(cond
(define (print-error-and-continue key . args)
"Frequently used as pre-unwind-handler for agenda"
(cond