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