From simon.urbanek at r-project.org  Tue May 20 19:22:34 2008
From: simon.urbanek at r-project.org (Simon Urbanek)
Date: Tue, 20 May 2008 13:22:34 -0400
Subject: [Rd] interrupting native code
In-Reply-To: <4BADEEEE-0C2C-496F-B5BC-B8A95C53FADC@epfl.ch>
References: <B2675BBE-97A5-4012-A855-6955F6EE8246@epfl.ch>
	<alpine.LFD.1.10.0805151533180.22788@gannet.stats.ox.ac.uk>
	<80A6B7A3-7979-4A70-8FBF-3EBA753E093E@epfl.ch>
	<alpine.LFD.1.10.0805161142330.27836@gannet.stats.ox.ac.uk>
	<A213708A-3BA2-4109-B24E-F862DCED9BBF@epfl.ch>
	<Pine.LNX.4.64.0805160635510.10050@itasca2.wildberry.org>
	<4BADEEEE-0C2C-496F-B5BC-B8A95C53FADC@epfl.ch>
Message-ID: <D1DDC014-AEDF-4DDC-9E07-5B469B1B32DA@r-project.org>


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



[Rd] interrupting native code
Simon Urbanek