Re: [Rd] sending signals to embedded R

From: Luke Tierney <luke_at_stat.uiowa.edu>
Date: Sat, 05 May 2007 12:40:23 -0500 (CDT)

On Sat, 5 May 2007, Prof Brian Ripley wrote:

> On Sat, 5 May 2007, Luke Tierney wrote:
>
>> On Sat, 5 May 2007, Prof Brian Ripley wrote:
>>
>>> On Fri, 4 May 2007, Luke Tierney wrote:
>>>
>>>> On Fri, 4 May 2007, Deepayan Sarkar wrote:
>>>>
>>>>> On 5/4/07, Prof Brian Ripley <ripley_at_stats.ox.ac.uk> wrote:
>>>>>> On Fri, 4 May 2007, Deepayan Sarkar wrote:
>>>>>>
>>>>>>> one thing I haven't been able to figure out from R-exts is how to
>>>>>>> interrupt a calculation running inside an embedded R. C code inside R
>>>>>>> calls R_CheckUserInterrupt() intermittently to check for interrupts,
>>>>>>> but how does my GUI tell R that the user wants it interrupted?
>>>>>>
>>>>>> Well, the intention is that you send an interrupt, which hardly needs
>>>>>> to
>>>>>> be in the manual.
>>>>>
>>>>> I didn't mean to imply that it does. I'm just new to signals and
>>>>> things that should be obvious aren't.
>>>>>
>>>>> Basically kill(2) seems to be the right thing to use, but I wasn't
>>>>> sure what the PID needs to be. Turns out sending SIGINT to my GUI from
>>>>> a shell interrupts R, so raise(SIGINT) should be enough.
>>>>
>>>> The tricky bit here is figuring out who does the sending. It you have
>>>> a separate thread/process for the GUI and R then that is fine (though
>>>> may raise other issues). If it is a single thread then you need your
>>>> event processing to get an occasional look in to recognise the user
>>>> action that triggers an interrupt. The Windows version handles this by
>>>> having R_CheckUserInterrupt() do a limited amount of event processing
>>>> (you need to be careful in GUI events have R actions associated with
>>>> them). I believe the Mac version is similar though it has been a
>>>
>>> I was assuming that Deepayan's GUI (which seems to need Qt4, BTW, so I was
>>> unable to compile it) worked via the R-Unix eventloop, in which case it
>>> gets some CPU time from time to time.

>>
>> I was assuming that as well. But my recollection is that on unix the
>> event loop is only run from within the console reader. On Windows
>> (and Mac OS X I believe) some event processing also happens in
>> R_CheckUserInterrupt(); on Windows there is also some more in some
>> blocking library calls, like socket reads as I recall. But unless
>> things have changed since I last looked none of that happens on unix.
>>
>>>
>>> gnomeGUI has an interrupt menu item with action 'onintr', which may well
>>> be what Deepayan is looking for: the only reason that package still exists
>>> is to provide example code. (Not that it was ever properly integrated
>>> with the R event loop.)
>>
>> It does have some sort of interrupt device (I can't recall if it is a
>> menu item or a butto and I can't seem to build a working gnomeGUI to
>> check). And I believe if you try to use that item (or button?) during
>> a long-running computation you can't because the events won't be
>> looked at until R gets back to a console read, at which point the
>> events will be processed and you jump to the top level (where you
>> already are).
>
> That belief is correct (it has a menu item and a button), but my final
> parenthetical remark was that gnomeGUI was not wedged into the event loop.
>
>>> If the issue is what happens when the user Ctrl-C's in the GUI console,
>>> that depends on what the GUI toolkit does with keyboard input: if it
>>> generates a SIGINT this should just work, but otherwise the keyboard
>>> handler needs to be told to call onintr() one way or another.
>>
>> Again only if the GUI gets a chance to look at the keyboard input,
>> which I don't think we currently give it.
>
> We builtin the ability for a front-end to register handlers with the R event
> loop, including a polling handler (and that is how we can have a Tcl/Tk front
> end). That postdates gnomeGUI, which runs the Gtk event-loop, not R's.
>

I had forgotten about that -- thanks for the reminder.

However, R_PolledEvents is only called from a limited set of places now (including the socket reading code to keep things responsive during blocking reads). But it is not called from the interupt checking code, which means if a user does something equivalent to

    while (TRUE) {}

there is not point where events get looked at to see a user interrupt action. The current definition of R_CheckUserInterrupt is

void R_CheckUserInterrupt(void)
{

     R_CheckStack();
     /* This is the point where GUI systems need to do enough event
        processing to determine whether there is a user interrupt event
        pending.  Need to be careful not to do too much event
        processing though: if event handlers written in R are allowed
        to run at this point then we end up with concurrent R
        evaluations and that can cause problems until we have proper
        concurrency support. LT */
#if  ( defined(HAVE_AQUA) || defined(Win32) )
     R_ProcessEvents();
#else
     if (R_interrupts_pending)
         onintr();

#endif /* Win32 */
}

So only on Windows or Mac do we do event processing. We could add a R_PolledEvents() call in the #else bit to support this, though the cautions in the comment do need to be kept in mind.

Best,

luke

> So my assumption 'worked via the R-Unix eventloop' was that a handler
> (probably a polling handler) had been wedged in the eventloop.
> That was in contrast to running under a separate thread.
>
>> The UI provided by a shell running in a separate process may not have
>> a 'G' but it does have its advantages :-)
>
> Or a separate thread, as Rterm.exe does. Really RGui should also run in a
> separate thread, but when Guido did so, it did not work under Windows 95: if
> we ever give up support for pre-NT Windows I will take a look again at this.
>
> I guess my underlying point is that rather than run the GUI from
> R_ProcessEvents (as RGui is), on Unix you can run it from an eventloop
> handler.
>
> Brian
>
>>
>> Best,
>>
>> luke
>>
>>>> while since I looked at that. I don't believe the unix version of
>>>> R_CheckUserInterrupt() does not provide hooks for installing such
>>>> checking (we have talked about this off an on but I don't believe
>>>> anything happened -- could be wrong there though).
>>>>
>>>> If Qt allows this one option may be to have events on your nterrupt
>>>> widget managed by a small thread that does nothing other than send a
>>>> signal to the main thread if the widget is clicked.
>>>>
>>>> Best,
>>>>
>>>> luke
>>>>
>>>>
>>>
>>>
>>
>>
>
>

-- 
Luke Tierney
Chair, Statistics and Actuarial Science
Ralph E. Wareham Professor of Mathematical Sciences
University of Iowa                  Phone:             319-335-3386
Department of Statistics and        Fax:               319-335-3017
    Actuarial Science
241 Schaeffer Hall                  email:      luke_at_stat.uiowa.edu
Iowa City, IA 52242                 WWW:  http://www.stat.uiowa.edu

______________________________________________
R-devel_at_r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel
Received on Sat 05 May 2007 - 17:44:56 GMT

Archive maintained by Robert King, hosted by the discipline of statistics at the University of Newcastle, Australia.
Archive generated by hypermail 2.2.0, at Sun 06 May 2007 - 22:33:26 GMT.

Mailing list information is available at https://stat.ethz.ch/mailman/listinfo/r-devel. Please read the posting guide before posting to the list.