[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