The hardware and bandwidth for this mirror is donated by dogado GmbH, the Webhosting and Full Service-Cloud Provider. Check out our Wordpress Tutorial.
If you wish to report a bug, or if you are interested in having us mirror your free-software or open-source project, please feel free to contact us at mirror[@]dogado.de.

Checking for Interrupts

Introduction

It is considered good practice to allow C code to be interupted if it runs for an extended period.

R_CheckUserInterrupt() checks whether the user is trying to interrupt (using ctrl-c or similar) and will immediately abort the execution of the code.

R_CheckUserInterrupt() example

In the folowing example, when interrupted, the Rprintf() and return statements will not be executed. Control will immediately return to the user’s R session.

#include <R.h>
#include <Rinternals.h>
#include <unistd.h>  // for 'sleep()'

SEXP interruptable_sleep(void) {
  while (1) {
    R_CheckUserInterrupt();  // abort if user interrupts. no recovery.
    sleep(1);
  }
  Rprintf("Never get here!  Interrupt causes immediate exit!");
  return R_NilValue;
}
Click to show R code
code = r"(
#include <R.h>
#include <Rinternals.h>
#include <unistd.h>  // for 'sleep()'

SEXP interruptable_sleep(void) {
  while (1) {
    R_CheckUserInterrupt();  // abort if user interrupts. no recovery.
    sleep(1);
  }
  Rprintf("Never get here!  Interrupt causes immediate exit!");
  return R_NilValue;
}
)"

callme::compile(code)
interruptable_sleep()

Continuing C execution after the interrupt

You may also wish to continue execution of the C code after the interrupt (e.g. to tidy and free any resources).

In this example the Rprintf() statment and return will be executed following the interuption.

#include <R.h>
#include <Rinternals.h>
#include <unistd.h>  // for 'sleep()'
#include <stdbool.h>

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// As suggested by Simon Urbanek
// https://stat.ethz.ch/pipermail/r-devel/2011-April/060702.html
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
static void check_interrupt_internal(void *dummy) {
  R_CheckUserInterrupt();
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// this will call the above in a top-level context so it won't 
// longjmp-out of your context
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
bool check_interrupt(void) {
  return (R_ToplevelExec(check_interrupt_internal, NULL) == FALSE);
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Your code goes here
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
SEXP interruptable_sleep2(void) {
  while (1) {
    if (check_interrupt()) break;  // break out of while(). Keep executing
    sleep(1);
  }
  Rprintf("My sleep was interrupted!\n");
  return R_NilValue;
}
Click to show R code
code = r"(
#include <R.h>
#include <Rinternals.h>
#include <unistd.h>  // for 'sleep()'
#include <stdbool.h>

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// As suggested by Simon Urbanek
// https://stat.ethz.ch/pipermail/r-devel/2011-April/060702.html
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
static void check_interrupt_internal(void *dummy) {
  R_CheckUserInterrupt();
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// this will call the above in a top-level context so it won't 
// longjmp-out of your context
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
bool check_interrupt(void) {
  return (R_ToplevelExec(check_interrupt_internal, NULL) == FALSE);
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Your code goes here
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
SEXP interruptable_sleep2(void) {
  while (1) {
    if (check_interrupt()) break;  // break out of while(). Keep executing
    sleep(1);
  }
  Rprintf("My sleep was interrupted!\n");
  return R_NilValue;
}
)"

callme::compile(code)
interruptable_sleep2()

These binaries (installable software) and packages are in development.
They may not be fully stable and should be used with caution. We make no claims about them.
Health stats visible at Monitor.