I have tested the solutions suggested by Simon and Thomas on a Linux machine. These are my findings:

On Windows you can look at the variable "UserBreak", available from
Rembedded.h. Outside of Windows, you can look at R_interrupts_pending,
available from R_ext/GraphicsDevice.h. R_ext/GraphicsDevice.h also has
R_interrupts_suspended, which you may or may not want to take into account,
depending on your use-case.
I did not manage to get this to work. Neither R_interrupts_pending nor R_interrupts_suspended seem to change when I press ctrl+c. Perhaps this is due to the fact that I run R in a terminal without any graphical interface?

static void chkIntFn(void *dummy) {
  R_CheckUserInterrupt();
}
// this will call the above in a top-level context so it won't longjmp-out of 
your context
bool checkInterrupt() {
  return (R_ToplevelExec(chkIntFn, NULL) == FALSE);
}
// your code somewhere ...
if (checkInterrupt()) { // user interrupted ... }
This solution works perfectly! It takes slightly longer to call this function than the plan R_CheckUserInterrupt() call, but in any reasonable scenario, the additional time is absolutely insignificant.

Inside OpenMP parallel for constructs, one has to make sure that only the thread satisfying omp_get_thread_num()==0 makes the call (the 'master' construct cannot be nested inside a loop). I can then set a flag, which is queried by every thread in every loop cycle, causing fast termination of the parallel loop. After the loop, I throw an exception. Thus, my code is terminated gracefully with minimal effort. I can do additional cleanup operations (which usually is not necessary, since I use smart pointers), and report details on the interrupt to the user.

With my limited testing, so far I have not noticed any downsides. Of course, there is the obvious drawback of not being supported officially (and thus maybe being subject to change), the question of portability, and the question of interoperability with other errors.

Moreover, I have found an old thread discussing almost the same topic:
http://tolstoy.newcastle.edu.au/R/e4/devel/08/05/1686.html .
The thread was created in 2008, so the issue is not really a new one. The solution proposed there is actually the same as the one suggested by Simon, namely using R_ToplevelExec().

An officially supported, portable solution would of course be much appreciated!


Best regards,
Peter

______________________________________________
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel

Reply via email to