Re: [Rd] Ignore user interrupts

From: <luke-tierney_at_uiowa.edu>
Date: Fri, 27 Jan 2012 08:25:11 -0600

On Thu, 26 Jan 2012, Sharpie wrote:

>
> Sharpie wrote
>>
>> evalWithoutInterrupts <- function(expr, envir = parent.frame())
>> {
>> .Call(do_evalWithoutInterrupts, expr, envir)
>> }
>>
>>
>> With a C-level implemention:
>>
>> SEXPR do_evalWithoutInterrupts(SEXP expr, SEXP envir)
>> {
>> SEXP result;
>>
>> BEGIN_SUSPEND_INTERRUPTS{
>> result = eval(expr, envir);
>> }END_SUSPEND_INTERRUPTS;
>>
>> return result;
>> }
>>
>
> Some more info, and a possible bug:
>
> This approach appears to work if I change `evalWithoutInterrupts` so that it
> invokes `substitute` on `expr` before passing to the C code:
>
>
> evalWithoutInterrupts <- function(expr, envir = parent.frame())
> {
> .Call(do_evalWithoutInterrupts, substitute(expr), envir)
> }
>
>
> For example, I can do the following (using OS X, R 2.14.1 in Terminal.app):
>
> eval({for(i in 1:10000000){log(i)};message("Hello, world!")})
> evalWithoutInterrupts({for(i in 1:10000000){log(i)};message("Hello,
> world!")})
>
> The `eval` call can be interrupted by CTRL-C as normal. However, with the
> `evalWithoutInterrupts` call, I can tap on CTRL-C and the loop will still
> execute, "Hello, world!" will be printed and then the interrupt will be
> registered:
>
> > evalWithoutInterrupts({for(i in 1:10000000){log(i)};message("Hello,
> world!")})
> ^C^C^C^C^CHello, world!
>
> >
>
>
> The only odd thing I came across was when I tried to test this function
> using `Sys.sleep` instead of a long loop:
>
> evalWithoutInterrupts(Sys.sleep(3);message("Hello, world!")})
>
> The call can be interrupted immediately by CTRL-C. Some poking in GDB
> reveals that the call chain passes from my C function
> `evalWithoutInterrupts` to `do_syssleep` an finally to `Rf_onintr` through
> `R_checkActivity`:
>
> Breakpoint 1, Rf_onintr () at errors.c:123
> 123 if (R_interrupts_suspended) {
> (gdb) bt
> #0 Rf_onintr () at errors.c:123
> #1 0x00000001001ced41 in R_SelectEx (n=1, readfds=0x10038cdc0,
> writefds=0x0, exceptfds=0x0, timeout=0x7fff5fbf8b60, intr=0) at
> sys-std.c:127
> #2 0x00000001001cf109 in R_checkActivityEx (usec=3000000, ignore_stdin=1,
> intr=0) at sys-std.c:329
> #3 0x00000001001cf14b in R_checkActivity (usec=3000000, ignore_stdin=1) at
> sys-std.c:338
> #4 0x00000001001d0fbb in do_syssleep (call=0x1025bb200, op=0x10086d0d8,
> args=0x1033679b8, rho=0x1033679f0) at sys-std.c:1299
> #5 0x00000001000c7608 in bcEval (body=0x1025ba878, rho=0x1033679f0,
> useCache=TRUE) at eval.c:4445
> #6 0x00000001000bcb69 in Rf_eval (e=0x1025ba878, rho=0x1033679f0) at
> eval.c:401
> #7 0x00000001000bddd7 in Rf_applyClosure (call=0x103366e38, op=0x1025ba8e8,
> arglist=0x103367a60, rho=0x100877ea8, suppliedenv=0x100877ee0) at eval.c:840
> #8 0x00000001000bd22e in Rf_eval (e=0x103366e38, rho=0x100877ea8) at
> eval.c:515
> #9 0x00000001000bf879 in do_begin (call=0x103366ee0, op=0x10084e6e0,
> args=0x103366dc8, rho=0x100877ea8) at eval.c:1422
> #10 0x00000001000bcf40 in Rf_eval (e=0x103366ee0, rho=0x100877ea8) at
> eval.c:471
> #11 0x0000000102fc736d in evalWithoutInterrupts ()
>
>
> However, at this point the variable `R_interrupts_suspended` is not set to
> `TRUE` as I would expect due to the `BEGIN_SUSPEND_INTERRUPTS` block in
> `evalWithoutInterrupts`:
>
> (gdb) p R_interrupts_suspended
> $1 = FALSE
>
>
> Bug?

No.

The interrupt managemant we have now is intended for the C level to make sure interrupts can only occur where they are safe for the C code, and at this point in sleep they are and so do_syssleep enables them.

There is a need for interrupt management at the R level but getting it right is not easy. It isn't just a matter of suspending them, but suspending and and re-enabling them where they are safe. Some code that would potentially hang needs to enable them -- typically these are operations that could signal other sorts of errors, like read errors, timeouts, etc. and code that needs to ensure cleanup code is run would need to catch those as well. (Interrupts are catchable as "interrupt" conditions by the way). There is some literature on this (in particular an article "Asynchronous Exceptions in Haskell") that I need to study more before implementing something at the R level.

luke

>
> -Charlie
>
>
> -----
> Charlie Sharpsteen
> Undergraduate-- Environmental Resources Engineering
> Humboldt State University
> --
> View this message in context: http://r.789695.n4.nabble.com/Ignore-user-interrupts-tp4321252p4331653.html
> Sent from the R devel mailing list archive at Nabble.com.
>
> ______________________________________________
> 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-tierney_at_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 Fri 27 Jan 2012 - 14:29:16 GMT

This quarter's messages: by month, or sorted: [ by date ] [ by thread ] [ by subject ] [ by author ]

All messages

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 Fri 27 Jan 2012 - 20:10:12 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.

list of date sections of archive