From felix at nfrac.org  Sat Jan 17 06:55:33 2009
From: felix at nfrac.org (Felix Andrews)
Date: Sat, 17 Jan 2009 16:55:33 +1100
Subject: [Rd] interrupting R from a GUI
In-Reply-To: <alpine.OSX.1.00.0901160612480.65436@tystie.local>
References: <94730b8a0901152207n4499c4e3n4352840334f025eb@mail.gmail.com>
	<alpine.OSX.1.00.0901160612480.65436@tystie.local>
Message-ID: <94730b8a0901162155j34a539aw4ecbbe656c2bfc80@mail.gmail.com>

2009/1/16 Prof Brian Ripley <ripley at stats.ox.ac.uk>:
> On Fri, 16 Jan 2009, Felix Andrews wrote:
>
>> 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
>
> Actually no, Rgui does not use that code (but Rterm does).
>
>> ?...but it is beyond me.
>
> 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.

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?


>
>> Any help would be appreciated.
>>
>> -Felix
>>
>> --
>> Felix Andrews / ???
>> http://www.neurofractal.org/felix/
>
> [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.]

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.


-- 
Felix Andrews / ???
http://www.neurofractal.org/felix/
3358 543D AAC6 22C2 D336  80D9 360B 72DD 3E4C F5D8



[Rd] interrupting R from a GUI
Felix Andrews