From 2764d8e78d0d72f7c0d8fcc4e41cf4df41017026 Mon Sep 17 00:00:00 2001
From: Kaz Kylheku <kaz@kylheku.com>
Date: Thu, 29 Oct 2015 06:46:05 -0700
Subject: Finalize obtain continuator function.

* share/txr/stdlib/yield.tl (sys:obtain-impl): Add a finalizer
to the returned closure which will feed sys:cont-poison object
to the most recently captured continuation. Thus abandoned
obtain blocks which have become garbage shall have their
unwinding performed.

* txr.1: Documented the finalization behavior.
---
 share/txr/stdlib/yield.tl | 17 ++++++++++-------
 txr.1                     | 10 ++++++++++
 2 files changed, 20 insertions(+), 7 deletions(-)

diff --git a/share/txr/stdlib/yield.tl b/share/txr/stdlib/yield.tl
index ef0518e6..ea9bb4d2 100644
--- a/share/txr/stdlib/yield.tl
+++ b/share/txr/stdlib/yield.tl
@@ -26,13 +26,16 @@
 (defstruct (sys:yld-item val cont) nil val cont)
 
 (defun sys:obtain-impl (fun)
-  (lambda (: reply)
-    (let ((yi (call fun reply)))
-      (cond
-        ((eq (typeof yi) 'sys:yld-item)
-         (set fun yi.cont)
-         yi.val)
-        (t yi)))))
+  (finalize
+    (lambda (: reply)
+      (let ((yi (call fun reply)))
+        (cond
+          ((eq (typeof yi) 'sys:yld-item)
+           (set fun yi.cont)
+           yi.val)
+          (t yi))))
+    (lambda (cont)
+      (call cont 'sys:cont-poison))))
 
 (defun sys:yield-impl (name fun ctx-form)
   (let ((cont (sys:capture-cont name ctx-form)))
diff --git a/txr.1 b/txr.1
index 71c8f5e8..cb239c93 100644
--- a/txr.1
+++ b/txr.1
@@ -27669,6 +27669,16 @@ if it is an ordinary value, it is returned; otherwise, if it is
 a yield object, its stored value is returned and the state is updated
 with the new yield object's continuation.
 
+The
+.code obtain
+macro registers a finalizer against the returned function.
+The finalizer invokes the function, passing it the symbol
+.codn sys:cont-poison ,
+thereby triggering unwinding in the most recently captured
+continuation. Thus, abandoned
+.code obtain
+blocks are subject to unwinding when they become garbage.
+
 .TP* Notes:
 
 These macros provide a simple abstraction for the use of continuations.
-- 
cgit v1.2.3