aboutsummaryrefslogtreecommitdiff
path: root/guix-build-coordinator/utils
diff options
context:
space:
mode:
authorChristopher Baines <mail@cbaines.net>2022-01-19 13:15:05 +0000
committerChristopher Baines <mail@cbaines.net>2022-01-19 13:15:05 +0000
commite43c265870b8abb4d9c69463e0eb4563553e23b2 (patch)
tree8762b01b8ad40f07439d9de5c0ab1a1a6b0e22a4 /guix-build-coordinator/utils
parent75c00fc1705d2f11b4e2972f0f1ce925db0d0a5c (diff)
downloadbuild-coordinator-e43c265870b8abb4d9c69463e0eb4563553e23b2.tar
build-coordinator-e43c265870b8abb4d9c69463e0eb4563553e23b2.tar.gz
Add letpar&
Mostly copied from the Guix Data Service.
Diffstat (limited to 'guix-build-coordinator/utils')
-rw-r--r--guix-build-coordinator/utils/fibers.scm58
1 files changed, 57 insertions, 1 deletions
diff --git a/guix-build-coordinator/utils/fibers.scm b/guix-build-coordinator/utils/fibers.scm
index a8b6738..5481191 100644
--- a/guix-build-coordinator/utils/fibers.scm
+++ b/guix-build-coordinator/utils/fibers.scm
@@ -10,7 +10,9 @@
call-with-sigint
- run-server/patched))
+ run-server/patched
+
+ letpar&))
(define %worker-thread-args
(make-parameter #f))
@@ -147,3 +149,57 @@ If already in the worker thread, call PROC immediately."
(set-nonblocking! socket)
(sigaction SIGPIPE SIG_IGN)
(spawn-fiber (lambda () (socket-loop socket handler))))))
+
+(define (defer-to-fiber thunk)
+ (let ((reply (make-channel)))
+ (spawn-fiber
+ (lambda ()
+ (put-message
+ reply
+ (with-exception-handler
+ (lambda (exn)
+ (cons 'worker-fiber-error exn))
+ (lambda ()
+ (with-exception-handler
+ (lambda (exn)
+ (simple-format
+ (current-error-port)
+ "worker fiber: exception: ~A\n"
+ exn)
+ (backtrace)
+ (raise-exception exn))
+ (lambda ()
+ (call-with-values
+ thunk
+ (lambda vals
+ vals)))))
+ #:unwind? #t)))
+ #:parallel? #t)
+ reply))
+
+(define (fetch-result-of-defered-thunks . reply-channels)
+ (let ((responses (map get-message reply-channels)))
+ (map
+ (match-lambda
+ (('worker-thread-error . exn)
+ (raise-exception exn))
+ (result
+ (apply values result)))
+ responses)))
+
+(define-syntax parallel-via-fibers
+ (lambda (x)
+ (syntax-case x ()
+ ((_ e0 ...)
+ (with-syntax (((tmp0 ...) (generate-temporaries (syntax (e0 ...)))))
+ #'(let ((tmp0 (defer-to-fiber
+ (lambda ()
+ e0)))
+ ...)
+ (apply values (fetch-result-of-defered-thunks tmp0 ...))))))))
+
+(define-syntax-rule (letpar& ((v e) ...) b0 b1 ...)
+ (call-with-values
+ (lambda () (parallel-via-fibers e ...))
+ (lambda (v ...)
+ b0 b1 ...)))