From simon.urbanek at r-project.org  Tue Sep 28 20:55:34 2010
From: simon.urbanek at r-project.org (Simon Urbanek)
Date: Tue, 28 Sep 2010 14:55:34 -0400
Subject: [Rd] checking user interrupts in C(++) code
In-Reply-To: <AANLkTikfpH46Jb7WF3b1Wv_tMs30vagvx2ZB1dKnu38k@mail.gmail.com>
References: <AANLkTikfpH46Jb7WF3b1Wv_tMs30vagvx2ZB1dKnu38k@mail.gmail.com>
Message-ID: <C5CD55A5-2313-4748-8F7F-CFB27136A22F@r-project.org>

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



[Rd] checking user interrupts in C(++) code
Simon Urbanek