[Rd] Ignore user interrupts
Sharpie
chuck at sharpsteen.net
Thu Jan 26 21:16:27 CET 2012
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?
-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.
More information about the R-devel
mailing list