summaryrefslogtreecommitdiff
path: root/src/cuirass/utils.scm
diff options
context:
space:
mode:
authorLudovic Courtès <ludo@gnu.org>2018-03-19 22:13:18 +0100
committerLudovic Courtès <ludo@gnu.org>2018-03-19 22:13:18 +0100
commite0e270986376b81a593553d9ee4b47b5cdb7a2ab (patch)
tree80268b63bca9fca55af17633f8282a642d65d55c /src/cuirass/utils.scm
parent787969c9af165113f67903173e3feb1a3e50f703 (diff)
downloadcuirass-e0e270986376b81a593553d9ee4b47b5cdb7a2ab.tar
cuirass-e0e270986376b81a593553d9ee4b47b5cdb7a2ab.tar.gz
utils: Add 'unwind-protect'.
* src/cuirass/utils.scm (unwind-protect): New macro.
Diffstat (limited to 'src/cuirass/utils.scm')
-rw-r--r--src/cuirass/utils.scm20
1 files changed, 20 insertions, 0 deletions
diff --git a/src/cuirass/utils.scm b/src/cuirass/utils.scm
index 947bf71..2e71910 100644
--- a/src/cuirass/utils.scm
+++ b/src/cuirass/utils.scm
@@ -32,6 +32,7 @@
object->json-scm
object->json-string
define-enumeration
+ unwind-protect
non-blocking
essential-task
bytevector-range))
@@ -67,6 +68,25 @@ value."
((_ symbol) value)
...)))
+(define-syntax-rule (unwind-protect body ... conclude)
+ "Evaluate BODY... and return its result(s), but always evaluate CONCLUDE
+before leaving, even if an exception is raised.
+
+This is *not* implemented with 'dynamic-wind' in order to play well with
+delimited continuations and fibers."
+ (let ((conclusion (lambda () conclude)))
+ (catch #t
+ (lambda ()
+ (call-with-values
+ (lambda ()
+ body ...)
+ (lambda results
+ (conclusion)
+ (apply values results))))
+ (lambda args
+ (conclusion)
+ (apply throw args)))))
+
(define (%non-blocking thunk)
(let ((channel (make-channel)))
(call-with-new-thread