[Rd] interrupting native code

Luke Tierney luke at stat.uiowa.edu
Wed May 21 16:22:27 CEST 2008


If you are using an external pointer you can register a finalizer that
does the cleanup at gc time in case of an abnormal exit.  Otherwise
you should for now be able to use R_ToplevelExec tigether with
R_CheckUserInterrupt as I suggested previously.

Best,

luke

On Wed, 21 May 2008, Kjell Konis wrote:

> I have a structure from a library that I am using an external pointer to keep 
> track of. The methods in this library (lp_solve) have the facility to call a 
> function periodically and I would like to use R_ProcessEvents. The problem is 
> that if an interrupt is requested then R returns to the command prompt 
> without completing the library method. This leaves the structure in a 
> messed-up state so that I can't even successfully delete it, potentially 
> leaking a lot of memory. So what I am trying to do is find a way to see if an 
> event has occurred (in this case an interrupt) so I can respond to it before 
> onintr() gets called.
>
> Kjell
>
>
> On 20 mai 08, at 19:22, Simon Urbanek wrote:
>
>> 
>> On May 20, 2008, at 10:58 AM, Kjell Konis wrote:
>> 
>>> I would actually prefer a mechanism that simply returns a flag indicating 
>>> that an interrupt has been requested. Then I would be able to clean up and 
>>> return on my own - no longjmp required. Also, it would be useful if there 
>>> was a function similar to R_ProcessEvents that only dealt with keeping the 
>>> GUI responsive.
>>> 
>> 
>> I don't understand what you mean by the last sentence - that is exactly 
>> what R_ProcessEvents is for - or am I missing something?
>> 
>> Cheers,
>> 
>> Simon
>> 
>> 
>>> Cheers,
>>> Kjell
>>> 
>>> 
>>> On 16 mai 08, at 13:54, Luke Tierney wrote:
>>> 
>>>> I'm not sure you can make this work as some of the things needed
>>>> either are or should be private to the core implementation and not
>>>> available to package code.  In any case I would not recommend this
>>>> approach for two reasons.  First, details of what happens in interrupt
>>>> checking are subject to change and your code would miss those changes
>>>> unless you track them carefully.  More importantly, several things
>>>> here could generate an error that results in a longjmp and leaves your
>>>> code in an unstable state.
>>>> 
>>>> What is needed for this is a mechanism for detecting an interrupt but
>>>> not doing the longjmp, just returning a flag that a longjmp is needed
>>>> and enough information to allow it to be made after cleanup code has
>>>> been run.  This has been on my to do list for a while but getting the
>>>> semantics right is tricky and so it hasn't happened yet.  Hopefully it
>>>> will be in 2.8.0.  In the interim you can cobble something together
>>>> using R_ToplevelExec, interpreting all FALSE return values as user
>>>> interrupts.
>>>> 
>>>> Another option, also under consideration but not available yet, is a C
>>>> mechanism for registering cleanup operations if a longjmp occurs.  A
>>>> quick and dirty version of that could be provided fairly easily but a
>>>> better version, which would be preferable in the long run, requires a
>>>> rewrite of the code that implements jumps and cleanup/on.exit actions.
>>>> This may take a bit longer to implement.
>>>> 
>>>> Best,
>>>> 
>>>> luke
>>>> 
>>>> On Fri, 16 May 2008, Kjell Konis wrote:
>>>> 
>>>>> You mean something like this (I return 1 instead of calling onintr())? 
>>>>> Will HAVE_AQUA and Win32 be appropriately defined when building my 
>>>>> package (I can't see how to check with R CMD config)?
>>>>> 
>>>>> int My_CheckUserInterrupt(void)
>>>>> {
>>>>> R_CheckStack();
>>>>> 
>>>>> #if  ( defined(HAVE_AQUA) )
>>>>> 
>>>>> /* R_ProcessEvents() from unix/aqua.c*/
>>>>> 
>>>>> if (ptr_R_ProcessEvents)
>>>>> ptr_R_ProcessEvents();
>>>>> if (R_interrupts_pending)
>>>>> return(1);
>>>>> 
>>>>> #elseif ( defined(Win32) )
>>>>> 
>>>>> /* R_ProcessEvents() from gnuwin32/system.c */
>>>>> 
>>>>> while (peekevent()) doevent();
>>>>> if (UserBreak) {
>>>>> 	UserBreak = FALSE;
>>>>> 	return(1);
>>>>> }
>>>>> R_CallBackHook();
>>>>> if(R_tcldo) R_tcldo();
>>>>> 
>>>>> #else
>>>>> 
>>>>> R_PolledEvents();
>>>>> if (R_interrupts_pending)
>>>>> 	return(1);
>>>>> 
>>>>> #endif
>>>>> 
>>>>> return(0);
>>>>> }
>>>>> 
>>>>> 
>>>>> 
>>>>> 
>>>>> On 16 mai 08, at 12:43, Prof Brian Ripley wrote:
>>>>> 
>>>>>> On Fri, 16 May 2008, Kjell Konis wrote:
>>>>>>> The problem is that my package uses an external pointer to keep track 
>>>>>>> of a structure created by the lp_solve library. If I use 
>>>>>>> R_CheckUserInterrupt in the lp_solve abort function it leaves the 
>>>>>>> structure in a messed-up state after an interrupt occurs. I am not 
>>>>>>> even able to free the memory allocated in the structure. I need to be 
>>>>>>> able to tell the lp_solve functions to interrupt themselves if I am 
>>>>>>> going to support interrupts at all.
>>>>>>> I took a longer look at errors.c and it seems my solution should work 
>>>>>>> as long as neither HAVE_AQUA nor Win32 are defined. Under the 
>>>>>>> circumstances, I think that's the best I can do.
>>>>>>> Any suggestions for a UI independent way to check for interrupts would 
>>>>>>> be appreciated.
>>>>>> Why not use the same code as R_CheckUserInterrupt but instead of 
>>>>>> calling onintr, call your own interrupt routine?
>>>>>>> Thanks,
>>>>>>> Kjell
>>>>>>> On 15 mai 08, at 16:41, Prof Brian Ripley wrote:
>>>>>>>> How is R_interrupts_pending going to be set?
>>>>>>>> It is set in the interrupt handler for SIGINT, but that is not the 
>>>>>>>> only way to indicate an interrupt, and it is not necessarily 
>>>>>>>> available to users of GUIs and embedded R.
>>>>>>>> Without servicing the GUIs all interaction will be dead, including 
>>>>>>>> sending an interrrupt from menus/buttons/keyboard.  See the comment 
>>>>>>>> in the code for R_CheckUserInterrupt.
>>>>>>>> On Thu, 15 May 2008, Kjell Konis wrote:
>>>>>>>>> Hello,
>>>>>>>>> I have some native code that I would like to allow users to 
>>>>>>>>> interrupt. However, I would like to do it more gracefully than with 
>>>>>>>>> R_CheckUserInterrupt(). The solution I came up with is to call the 
>>>>>>>>> following abort function periodically - if it returns 1 then I clean 
>>>>>>>>> up and return.
>>>>>>>>> int __WINAPI RlpSolveAbortFunction(lprec *lp, void *userhandle)
>>>>>>>>> {
>>>>>>>>> if(R_interrupts_pending)
>>>>>>>>> return(1);
>>>>>>>>> return(0);
>>>>>>>>> }
>>>>>>>>> This seems to work fine on Mac (sans Aqua) and Linux. Is this going 
>>>>>>>>> to be portable?  Also, is there anything else I need to do?  For 
>>>>>>>>> instance set R_interrupts_pending to 0 after I respond to it?
>>>>>>>>> Thanks.
>>>>>>>>> Kjell
>>>>>>>>> ______________________________________________
>>>>>>>>> R-devel at r-project.org mailing list
>>>>>>>>> https://stat.ethz.ch/mailman/listinfo/r-devel
>>>>>>>> -- 
>>>>>>>> Brian D. Ripley,                  ripley at stats.ox.ac.uk
>>>>>>>> Professor of Applied Statistics,  http://www.stats.ox.ac.uk/~ripley/
>>>>>>>> University of Oxford,             Tel:  +44 1865 272861 (self)
>>>>>>>> 1 South Parks Road,                     +44 1865 272866 (PA)
>>>>>>>> Oxford OX1 3TG, UK                Fax:  +44 1865 272595
>>>>>>> ______________________________________________
>>>>>>> R-devel at r-project.org mailing list
>>>>>>> https://stat.ethz.ch/mailman/listinfo/r-devel
>>>>>> -- 
>>>>>> Brian D. Ripley,                  ripley at stats.ox.ac.uk
>>>>>> Professor of Applied Statistics,  http://www.stats.ox.ac.uk/~ripley/
>>>>>> University of Oxford,             Tel:  +44 1865 272861 (self)
>>>>>> 1 South Parks Road,                     +44 1865 272866 (PA)
>>>>>> Oxford OX1 3TG, UK                Fax:  +44 1865 272595
>>>>> 
>>>>> ______________________________________________
>>>>> R-devel at r-project.org mailing list
>>>>> https://stat.ethz.ch/mailman/listinfo/r-devel
>>>> 
>>>> -- 
>>>> 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
>>> 
>>> 
>> 
>
> ______________________________________________
> R-devel at r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-devel

-- 
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



More information about the R-devel mailing list