Skip to content
Prev 43393 / 63424 Next

Capturing signals from within external libs

Jeff,
On May 22, 2012, at 4:31 PM, Jeffrey Ryan wrote:

            
Assuming that while in the library there are no R calls (important!), you can use setjmp/longjmp to branch your code depending on whether you raise an interrupt or not (see below). This also makes sure that you process things on the R side properly

Another alternative is to run your library call on a separate thread and have R wait for the result. In that case you don't need to mess with interrupts since your library code will run separately from R. The downside is that you need to mess with threads which may or may not be an issue depending on the complexity of your code and whether you want it to be cross-platform or not.

Cheers,
Simon


Example code:

#include <signal.h>
#include <setjmp.h>
#include <unistd.h>

#include <Rinternals.h>
#include <R_ext/GraphicsEngine.h> /* only needed if you use R_interrupts_pending */

static jmp_buf jenv;

static void my_int(int sig) {
  longjmp(jenv, 1); /* this also restores the interrupt handlers */
}

SEXP my_R_function(...) {

if (setjmp(jenv) == 0) { /* enter your protected code */
  void (*old_sig)(int);
  old_sig = signal(SIGINT, my_int);
  /* call your library here */
  /* restore original INT handler */
 signal(SIGINT, old_sig);
} else { /* this will get called on interrupt */
  /* you can do what you want - you're back to R-safe code here, so you can either raise an error or return from your function */
  /* if you want to trigger regular R interrupt handling, use this: */
   R_interrupts_pending = 1;
   R_CheckUserInterrupt();
  /* the above should not return */
}