From hb at biostat.ucsf.edu  Sat Apr  2 23:34:20 2011
From: hb at biostat.ucsf.edu (Henrik Bengtsson)
Date: Sat, 2 Apr 2011 14:34:20 -0700
Subject: [Rd] reg.finalizer(): Multiple finalizers?
Message-ID: <BANLkTin2soPo6kAeUJwW6sD5jiVvft7i6A@mail.gmail.com>

Hi,

I've got some questions regarding finalizers registered using
reg.finalizer().  I have a setup where in certain cases I wish to set
a new finalizer to an object that already got one.  Since there is no
API for removing/replacing already registered finalizers (have been
"requested" previously on this list), I have basically just added a
new finalizer by calling reg.finalizer() a second time.  This seems to
work (from being used for years), but it is not a documented property,
so it got me wondering.


Q1. Is it ok to register multiple finalizers this way, i.e. calling
reg.finalizer() multiple times on the same object?

Q2. If so, is the order in which the finalizers are called deterministic?

Q3. Is there a particular reason for not being able to replace/remove
existing finalizers?  I've tried to backtrack the code for
reg.finalizer() and I see a FINALIZE_ON_EXIT_MASK flag being set.
Could this be unset equally easy as setting it, or is there more to
it?


Regarding Q2: When running the below tests on Windows with R v2.12.2
patched, v2.13.0 beta, v2.14.0 devel, it seems that there is a
last-in-first-out ordering of how the finalizers are called - is that
an intended property?


# Clean up
rm(env); gc();

for (kk in 1:100) {
  s <- c();

  # Create a new environment
  env <- new.env();

  # Register Finalizer A
  reg.finalizer(env, function(env) s <<- c(s, "A"));

  # Register Finalizer B
  reg.finalizer(env, function(env) s <<- c(s, "B"));

  # Register Finalizer C
  reg.finalizer(env, function(env) s <<- c(s, "C"));

  # Trigger cleanup
  rm(env); gc();

  # Display order
  print(s);

  # Test hypothesis
  stopifnot(all.equal(s, c("C", "B", "A")));
} # for (kk ...)


Thanks

Henrik



[Rd] reg.finalizer(): Multiple finalizers?
Henrik Bengtsson