interrupting native code
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