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@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-tier...@uiowa.edu
Iowa City, IA 52242 WWW: http://www.stat.uiowa.edu
______________________________________________
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel