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

Berwin A Turlach berwin at maths.uwa.edu.au
Wed Sep 29 17:34:08 CEST 2010


G'day Simon,

since Karl brought up this topic, I thought I might use it to seek
clarification for something that bothered me for some time.

On Tue, 28 Sep 2010 14:55:34 -0400
Simon Urbanek <simon.urbanek at r-project.org> wrote:

> 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.

But what about objects created by allocVector() or NEW_XXXX in C code
that is called via .Call that need to be PROTECT'd?

The "Writing R Extensions" manual states:

	The programmer is solely responsible for housekeeping the calls
	to @code{PROTECT}.  There is a corresponding macro
	@code{UNPROTECT} that takes as argument an @code{int} giving
	the number of objects to unprotect when they are no longer
	needed.  The protection mechanism is stack-based, so
	@code{UNPROTECT(@var{n})} unprotects the last @var{n} objects
	which were protected.  The calls to @code{PROTECT} and
	@code{UNPROTECT} must balance when the user's code returns.
	@R{} will warn about @code{"stack imbalance in .Call"} (or
	@code{.External}) if the housekeeping is wrong.

If a call to R_CheckUserInterrupt() may not return, does that mean that
you should not call this function while you have objects PROTECT'd?

Even more, the section on R_CheckUserInterrupt() states:

	Note that it is possible that the code behind one of the entry
	points defined here if called from your C or FORTRAN code could
	be interruptible or generate an error and so not return to your
	code.

This seems to imply that, if you have objects PROTECT'd in your code,
you shouldn't use any of the R API defined in Chapter 6 of the manual,
except if you know that it doesn't call R_CheckUserInterrupt(), and
there seems to be no documentation on which functions in the API do and
which don't.

I guess my question is, essentially, does the PROTECT mechanism and
R_CheckUserInterrupt() play together nicely?  Can I call the latter
from code that has objects PROTECT'd?  If yes, and the code gets
interrupted, is the worse that happens a warning about a stack
imbalance, or will the R session become "unusable/unstable"?

Thanks in advance for any enlightening comments.

Cheers,

	Berwin



More information about the R-devel mailing list