agenda: When re-invoking a continuation at the agenda, don't wrap in a catch.
authorChristopher Allan Webber <cwebber@dustycloud.org>
Wed, 28 Dec 2016 17:49:05 +0000 (11:49 -0600)
committerChristopher Allan Webber <cwebber@dustycloud.org>
Wed, 28 Dec 2016 17:49:05 +0000 (11:49 -0600)
* 8sync/agenda.scm (<kontinue>): Add new record type which just wraps a
delimited continuation.
(8sync, 8sleep, 8yield): Wrap continuations in kontinue.
(agenda-run-once!): If "kontinue?", just resume the continuation without
catching errors (it already has an error handler!).

8sync/agenda.scm

index c177dd2baf6977761662ec0b6b3f0b8bb95b7462..3aa43da1eeec85dee0f6d9f9d58abe1d6084b558 100644 (file)
@@ -62,7 +62,7 @@
             stop-on-nothing-to-do
 
             %current-agenda-prompt
-            start-agenda agenda-run-once))
+            start-agenda agenda-run-once!))
 
 \f
 ;;; Agenda definition
@@ -350,6 +350,16 @@ Will produce (0 . 0) instead of a negative number, if needed."
   "Run BODY at DELAY-TIME time from now"
   (make-run-request (wrap body ...) (delayed-time delay-time)))
 
+;;; Procedures that are delimited continuations being resumed are
+;;; wrapped in a <kontinue>.  This is so that we don't accidentally
+;;; wrap in another catch statement every time we resume them, which
+;;; would be a drag.
+
+(define-record-type <kontinue>
+  (kontinue kont)
+  kontinue?
+  (kont kontinue-kont))
+
 
 \f
 ;;; Asynchronous escape to run things
@@ -385,10 +395,7 @@ forge ahead in our current function!"
    (make-async-request
     (lambda (kont)
       (list (make-run-request
-             ;; What's with returning #f to kont?
-             ;; Otherwise we sometimes get errors like
-             ;; "Zero values returned to single-valued continuation""
-             (wrap (kont #f)) #f)
+             (kontinue kont) #f)
             (make-run-request (lambda () body ...) #f))))))
 
 (define (delayed-time in-secs)
@@ -417,7 +424,7 @@ forge ahead in our current function!"
   (8sync-abort-to-prompt
    (make-async-request
     (lambda (kont)
-      (make-run-request (lambda () (kont #f)) (delayed-time secs))))))
+      (make-run-request (kontinue kont) (delayed-time secs))))))
 
 ;; Voluntarily yield execution
 (define (8yield)
@@ -425,7 +432,7 @@ forge ahead in our current function!"
   (8sync-abort-to-prompt
    (make-async-request
     (lambda (kont)
-      (make-run-request (lambda () (kont #f)) #f)))))
+      (make-run-request (kontinue kont) #f)))))
 
 \f
 ;;; Execution of agenda, and current agenda
@@ -618,14 +625,21 @@ on suspendable ports."
 (define (agenda-run-once! agenda)
   "Run once through the agenda, and produce a new agenda
 based on the results"
+  ;; @@: Maybe rename proc -> run-this ?
   (define (call-proc proc)
     (call-with-prompt
      (agenda-prompt-tag agenda)
      (lambda ()
-       (maybe-catch-all
-        ((agenda-catch-handler agenda)
-         (agenda-pre-unwind-handler agenda))
-        (proc)))
+       (if (kontinue? proc)
+           ;; Resume continuation.
+           ;; We need to pass in #f, otherwise we sometimes get errors like
+           ;; "Zero values returned to single-valued continuation""
+           ((kontinue-kont proc) #f)
+           ;; Otherwise call the procedure and set up error catching.
+           (maybe-catch-all
+            ((agenda-catch-handler agenda)
+             (agenda-pre-unwind-handler agenda))
+            (proc))))
      (lambda (kont async-request)
        (setup-async-request kont async-request))))