summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2018-02-28 18:48:44 -0800
committerKaz Kylheku <kaz@kylheku.com>2018-02-28 18:48:44 -0800
commitdf3789cfece5eaa149d76b07eda310c607288fbb (patch)
tree4aa7e08ee185330a3f0f9c418dc7b64265152b1f
parent92a40d9b424295ad8f62cad590b3862b1e6a54e0 (diff)
downloadtxr-df3789cfece5eaa149d76b07eda310c607288fbb.tar.gz
txr-df3789cfece5eaa149d76b07eda310c607288fbb.tar.bz2
txr-df3789cfece5eaa149d76b07eda310c607288fbb.zip
bugfix: missing actions in reset-struct.
* struct.c (reset_struct): Perform the post-init actions are performed, not only the init actions. Also, catch exceptions and call finalizers, just like in a new structure instantiation. * txr.1: Document the requirements for finalizers being called by reset-struct, and clarify the issue of possible duplicate finalization registration. Add compat notes.
-rw-r--r--struct.c16
-rw-r--r--txr.131
2 files changed, 46 insertions, 1 deletions
diff --git a/struct.c b/struct.c
index 6178340b..0e8b1080 100644
--- a/struct.c
+++ b/struct.c
@@ -726,14 +726,30 @@ val reset_struct(val strct)
struct struct_inst *si = struct_handle(strct, self);
struct struct_type *st = si->type;
cnum i;
+ volatile val inited = nil;
+ int compat_190 = opt_compat && opt_compat <= 190;
check_init_lazy_struct(strct, si);
+ uw_simple_catch_begin;
+
for (i = 0; i < st->nslots; i++)
si->slot[i] = nil;
call_initfun_chain(st, strct);
+ if (!compat_190)
+ call_postinitfun_chain(st, strct);
+
+ inited = t;
+
+ uw_unwind {
+ if (!inited && !compat_190)
+ gc_call_finalizers(strct);
+ }
+
+ uw_catch_end;
+
return strct;
}
diff --git a/txr.1 b/txr.1
index 7264bb2e..a8a482b2 100644
--- a/txr.1
+++ b/txr.1
@@ -24773,7 +24773,8 @@ and no boa arguments.
Note that finalizers registered against
.meta struct-obj
-are not invoked, and remain registered.
+are not invoked prior to the reset operation, and remain registered.
+
If the structure has state which is cleaned up by
finalizers, it is advisable to invoke them using
.code call-finalizers
@@ -24782,6 +24783,24 @@ prior to using
or to take other measures to deal with the
situation.
+If the structure specifies
+.code :fini
+handlers, then the reinitialization will cause
+these to registered, just like when a new object
+it constructed. Thus if
+.code call-finalizers
+is not used prior to
+.codn reset-struct ,
+this will result in the existence of duplicate registrations of the
+finalization functions.
+
+Finalizers registered against
+.meta struct-obj
+.B are
+invoked if an exception is thrown
+during the reinitialization, just like when a new
+structure is being constructed.
+
.coNP Function @ replace-struct
.synb
.mets (replace-struct < target-obj << source-obj )
@@ -63207,6 +63226,16 @@ of these version values, the described behaviors are provided if
is given an argument which is equal or lower. For instance
.code "-C 103"
selects the behaviors described below for version 105, but not those for 102.
+.IP 190
+Until \*(TX 190, the
+.code reset-struct
+function neglected to perform
+.code :postinit
+initializations, and didn't invoke finalization on the structure object
+if an exception was thrown during reinitialization. Thus, contrary
+to documented requirements, reinitialization of a structure didn't behave
+like fresh construction. This behavior is replicated if compatibility
+with 190 or earlier is requested.
.IP 188
Until \*(TX 188,
.codn equal -based