Karl,
On Sep 28, 2010, at 12:52 PM, Karl Forner wrote:
> My problem is that I have an extension in C++ that can be quite
time-consuming. I'd like to make it interruptible.
> The problem is that if I use the recommended R_CheckUserInterrupt() method
I have no possibility to cleanup (e.g. free the memory).
>
You do and if you allow interrupts you have to. If you play by the rules, you
don't need to do it specifically since R will take care of that.
Interrupting an operation is far more complex than just signaling the interrupt
- it involves collection of everything that needs to be cleaned on the way and
your code is only a small part of it. The reason why interrupt is not allowed in
random code is exactly that it's unsafe as many things could break and leak.
When you use R_CheckUserInterrupt() you're vouching for your code that it is
well written and will behave reasonably in the case of an interrupt.
There are several ways in which you can make your code respond to interrupts
properly - which one is suitable depends on your application. Probably the most
commonly used for interfacing foreign objects is to create an external pointer
with a finalizer - that makes sure the object is released even if you pass it on
to R later. For memory allocated within a call you can either use R's
transient memory allocation (see Salloc) or use the on.exit handler to cleanup
any objects you allocated manually and left over.
> I've seen an old thread about this, but I wonder if there's a new
and
> definitive answer.
>
> I just do not understand why a simple R_CheckUserInterrupt() like method
> returning a boolean could not be used.
Because that won't help since it involves running the event loop (otherwise
users would have no way of actually triggering it) which in turn could trigger
error handing and thus not return to your function, either. BTW: pretty much any
call to R can trigger an error, so R_CheckUserInterrupt() is not the only place
that requires you to think about cleanup.
Cheers,
Simon