- (let loop ((agenda agenda))
- (let ((agenda
- ;; @@: Hm, maybe here would be a great place to handle
- ;; select'ing on ports.
- ;; We could compose over agenda-run-once and agenda-read-ports
- (agenda-run-once agenda)))
- (if (and stop-condition (stop-condition agenda))
- 'done
- (let* ((agenda
- ;; We have to update the time after ports handled, too
- ;; because it may have changed after a select
- (set-field
- (handle-ports
- ;; Adjust the agenda's time just in time
- ;; We do this here rather than in agenda-run-once to make
- ;; agenda-run-once's behavior fairly predictable
- (set-field agenda (agenda-time) (get-time)))
- (agenda-time) (get-time))))
- ;; Update the agenda's current queue based on
- ;; currently applicable time segments
- (add-segments-contents-to-queue!
- (schedule-extract-until! (agenda-schedule agenda) (agenda-time agenda))
- (agenda-queue agenda))
- (loop agenda))))))
-
-(define (agenda-run-once agenda)
+ (install-suspendable-ports!)
+ (parameterize ((%current-agenda-prompt (agenda-prompt-tag agenda))
+ (current-read-waiter wait-for-readable)
+ (current-write-waiter wait-for-writable))
+ (while (not (stop-condition agenda))
+ (agenda-run-once! agenda)
+ (update-agenda-from-select! agenda)
+ (add-segments-contents-to-queue!
+ (schedule-extract-until! (agenda-schedule agenda) (gettimeofday))
+ (agenda-queue agenda))
+ (if post-run-hook
+ (post-run-hook agenda))))
+ 'done)
+
+(define (print-error-and-continue key . args)
+ "Frequently used as pre-unwind-handler for agenda"
+ (cond
+ ((eq? key '8sync-caught-error)
+ (match args
+ ((orig-key orig-args stacks)
+ (display "\n*** Caught async exception. ***\n")
+ (format (current-error-port)
+ "* Original key '~s and arguments: ~s *\n"
+ orig-key orig-args)
+ (display "* Caught stacks below (ending with original) *\n\n")
+ (for-each
+ (lambda (s)
+ (display-backtrace s (current-error-port))
+ (newline (current-error-port)))
+ stacks))))
+ (else
+ (format (current-error-port)
+ "\n*** Caught exception with key '~s and arguments: ~s ***\n"
+ key args)
+ (display-backtrace (make-stack #t 1 0)
+ (current-error-port))
+ (newline (current-error-port)))))
+
+(define-syntax-rule (maybe-catch-all (catch-handler pre-unwind-handler)
+ body ...)
+ (if (or catch-handler pre-unwind-handler)
+ (catch
+ #t
+ (lambda ()
+ body ...)
+ (or catch-handler (lambda _ #f))
+ (or pre-unwind-handler (lambda _ #f)))
+ (begin body ...)))
+
+(define (wait-for-readable port)
+ (8sync-abort-to-prompt
+ (make-async-request
+ (lambda (kont)
+ (make-read-request port (wrap (kont #f)))))))
+
+(define (wait-for-writable port)
+ (8sync-abort-to-prompt
+ (make-async-request
+ (lambda (kont)
+ (make-write-request port (wrap (kont #f)))))))
+
+(define (agenda-run-once! agenda)