Skip to content

interrupting R from a GUI

3 messages · Felix Andrews, Brian Ripley

#
list(...),

I am looking for a way to interrupt R from a callback: specifically,
to interrupt plotting (typically on a cairoDevice, but would be good
if it worked with other devices too). Of course, one can interrupt R
nicely from the console with Ctrl-C (or Esc in Rgui), but I need to do
it from a GUI. Callbacks run in a new thread, so obviously stop() etc
will not work. I tried to look into how Rgui does it...
https://svn.r-project.org/R/trunk/src/gnuwin32/psignal.c
?...but it is beyond me.

Alternatively, might there be a way to tell the cairoDevice widget to
stop drawing, somehow?

Any help would be appreciated.

-Felix
#
On Fri, 16 Jan 2009, Felix Andrews wrote:

            
Actually no, Rgui does not use that code (but Rterm does).
In detail this is OS-specific, but what the front-ends do is to set a 
flag or send a signal to R: look e.g. at rterm.c:

static void my_onintr(int nSig)
{
   UserBreak = 1;
   PostThreadMessage(mainThreadId,0,0,0);
}

or onintr in errors.c (which is called when UserBreak = 1, from the 
ain thread).  In due course R_interrupts_pending gets set and then at 
an appropriate spot R stops and unwinds the currrent evaluations.

The relevant Windows code is even in 'Writing R Extensions'.

So depending on your OS you can raise a signal or set a flag.  You can 
raise a signal on Windows too, so 'raise' is the most portable 
solution -- but beware that threading models differ.
Why not ask its author?
[Those seeking technical advice will increase their chances of help by 
giving their affiliation(s) or at least explaining the purpose of the 
request so that potential helpers know it is non-commercial.  You may 
not get the benefit of the doubt next time.]
#
2009/1/16 Prof Brian Ripley <ripley at stats.ox.ac.uk>:
Dear Professor Ripley,

Many thanks for your information-rich response.

I have not looked at serious C code before, so I find the R source
code quite confusing.

This is what I have come up with (as my package's src/interrupt.c):

#include <signal.h>

#ifdef WIN32
extern int UserBreak;
#endif

void do_interrupt(void)
{
#ifdef WIN32
    UserBreak = 1;
    //raise(SIGBREAK);
#else
    raise(SIGINT);
#endif
}

This seems to work under Rgui and Rterm on windows XP. I have not
tested it on linux or macOS. Does it look reasonable?
Fair enough; this is for the playwith package, which is GPL'd, and
(sadly) has no commercial links or prospects. I am affiliated in
various ways with the Australian National University.