Re: [Rd] Capturing signals from within external libs

2012-05-23 Thread Jeffrey Ryan
Simon,

Thanks for the clarifying example.  I fear my current set up fails the
test for 'no R calls', so I think I am stuck on the ugly variant for my
current challenge, but I will be able to use this in other places.

Thanks again,
Jeff

On 5/22/12 4:45 PM, Simon Urbanek simon.urba...@r-project.org wrote:

Jeff,

On May 22, 2012, at 4:31 PM, Jeffrey Ryan wrote:

 I have a continuous loop running in an external library that I am
calling
 from C (R API).  This loop is processing events in real time with the
 possibility of significant lag between events.
 
 When processing an event, I can make use of R_CheckUserInterrupt, but
 while the external library code is waiting on a new event, I don't have
an
 opportunity to call this - my entry points are only on events.
 

Assuming that while in the library there are no R calls (important!), you
can use setjmp/longjmp to branch your code depending on whether you raise
an interrupt or not (see below). This also makes sure that you process
things on the R side properly

Another alternative is to run your library call on a separate thread and
have R wait for the result. In that case you don't need to mess with
interrupts since your library code will run separately from R. The
downside is that you need to mess with threads which may or may not be an
issue depending on the complexity of your code and whether you want it to
be cross-platform or not.

Cheers,
Simon


Example code:

#include signal.h
#include setjmp.h
#include unistd.h

#include Rinternals.h
#include R_ext/GraphicsEngine.h /* only needed if you use
R_interrupts_pending */

static jmp_buf jenv;

static void my_int(int sig) {
  longjmp(jenv, 1); /* this also restores the interrupt handlers */
}

SEXP my_R_function(...) {

if (setjmp(jenv) == 0) { /* enter your protected code */
  void (*old_sig)(int);
  old_sig = signal(SIGINT, my_int);
  /* call your library here */
  /* restore original INT handler */
 signal(SIGINT, old_sig);
} else { /* this will get called on interrupt */
  /* you can do what you want - you're back to R-safe code here, so you
can either raise an error or return from your function */
  /* if you want to trigger regular R interrupt handling, use this: */
   R_interrupts_pending = 1;
   R_CheckUserInterrupt();
  /* the above should not return */
}



 I can capture a SIGINT by redefining signal(SIGINT, myhandler) before
 calling the lib, but I am somewhat at a loss in terms of what I can do
 within the handler that would let me pass control back to R.
 
 void myhandler (int s) {
  error(interrupt caught!);
 }
 
 Works, but I am sure it isn't supposed to.  In fact I know it is wrong,
 since after interrupting once SIGINTs are subsequently ignored, even if
I
 reset the signal to the original one (as returned by the first call to
 signal).
 
 Currently I can exit(1) of course, but that is tragically bad form IMO,
 though will work in my situation.
 
 In short, what is the proper way to handle SIGINT in external code that
is
 called from R, that allows R to handle the signal.  Thoughts or
 suggestions appreciated.
 
 Thanks,
 Jeff
 
 __
 R-devel@r-project.org mailing list
 https://stat.ethz.ch/mailman/listinfo/r-devel
 
 


__
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel


Re: [Rd] Capturing signals from within external libs

2012-05-23 Thread Simon Urbanek

On May 23, 2012, at 12:40 PM, Jeffrey Ryan wrote:

 Simon,
 
 Thanks for the clarifying example.  I fear my current set up fails the
 test for 'no R calls',

Well, but in that case you already have interrupt points so I'm not sure what 
is the problem? I thought the whole point is that you have long processing in 
some 3rd party library where you can't call R API so that's why you need the 
hack in the first place ...


 so I think I am stuck on the ugly variant for my
 current challenge, but I will be able to use this in other places.
 
 Thanks again,
 Jeff
 
 On 5/22/12 4:45 PM, Simon Urbanek simon.urba...@r-project.org wrote:
 
 Jeff,
 
 On May 22, 2012, at 4:31 PM, Jeffrey Ryan wrote:
 
 I have a continuous loop running in an external library that I am
 calling
 from C (R API).  This loop is processing events in real time with the
 possibility of significant lag between events.
 
 When processing an event, I can make use of R_CheckUserInterrupt, but
 while the external library code is waiting on a new event, I don't have
 an
 opportunity to call this - my entry points are only on events.
 
 
 Assuming that while in the library there are no R calls (important!), you
 can use setjmp/longjmp to branch your code depending on whether you raise
 an interrupt or not (see below). This also makes sure that you process
 things on the R side properly
 
 Another alternative is to run your library call on a separate thread and
 have R wait for the result. In that case you don't need to mess with
 interrupts since your library code will run separately from R. The
 downside is that you need to mess with threads which may or may not be an
 issue depending on the complexity of your code and whether you want it to
 be cross-platform or not.
 
 Cheers,
 Simon
 
 
 Example code:
 
 #include signal.h
 #include setjmp.h
 #include unistd.h
 
 #include Rinternals.h
 #include R_ext/GraphicsEngine.h /* only needed if you use
 R_interrupts_pending */
 
 static jmp_buf jenv;
 
 static void my_int(int sig) {
 longjmp(jenv, 1); /* this also restores the interrupt handlers */
 }
 
 SEXP my_R_function(...) {
 
 if (setjmp(jenv) == 0) { /* enter your protected code */
 void (*old_sig)(int);
 old_sig = signal(SIGINT, my_int);
 /* call your library here */
 /* restore original INT handler */
 signal(SIGINT, old_sig);
 } else { /* this will get called on interrupt */
 /* you can do what you want - you're back to R-safe code here, so you
 can either raise an error or return from your function */
 /* if you want to trigger regular R interrupt handling, use this: */
  R_interrupts_pending = 1;
  R_CheckUserInterrupt();
 /* the above should not return */
 }
 
 
 
 I can capture a SIGINT by redefining signal(SIGINT, myhandler) before
 calling the lib, but I am somewhat at a loss in terms of what I can do
 within the handler that would let me pass control back to R.
 
 void myhandler (int s) {
 error(interrupt caught!);
 }
 
 Works, but I am sure it isn't supposed to.  In fact I know it is wrong,
 since after interrupting once SIGINTs are subsequently ignored, even if
 I
 reset the signal to the original one (as returned by the first call to
 signal).
 
 Currently I can exit(1) of course, but that is tragically bad form IMO,
 though will work in my situation.
 
 In short, what is the proper way to handle SIGINT in external code that
 is
 called from R, that allows R to handle the signal.  Thoughts or
 suggestions appreciated.
 
 Thanks,
 Jeff
 
 __
 R-devel@r-project.org mailing list
 https://stat.ethz.ch/mailman/listinfo/r-devel
 
 
 
 
 
 

__
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel


Re: [Rd] Capturing signals from within external libs

2012-05-23 Thread Jeffrey Ryan
Simon,

Very likely butchered my initial problem explanation. The issue is that I
make a call to a library, something like:

SEXP my_fun() {
...
CB = MyCallback(XYZ);  /* this contains callback functions that in turn
use R */
externalLibCall(CB); /* infinite loop that won't return as it is
capturing streaming data */

/* we never get here */

Return(R_NilValue);
}

My callbacks look something like

on_event_A () {
  R_CheckUserInterrupt():
  evalRFunctionFromC();
}

But event_A only gets called when a new message arrives.  When a new
message arrives the on_event_A gets called from within the external
library code (hence calling R), but only when a message arrives.

At this point R_CheckUserInterrupt() works just fine.  The problem is when
the external process is waiting on a new message.  I have no entry to
check whether or not a message is available, nothing akin to select().
Basically I only get control in my callback when a new message happens.
So if there is no new message (in the context above it is a message/tick
from an exchange), the process spins/waits/not too sure what happens
internally, but the net result is I don't see anything.  I am waiting.  It
is at this point that I want to force an interrupt.

My current solution is just to redefine as my SIGINT handler before the
externalLibCall call, with an ungraceful exit() internal to it.  Dirty,
but lets me break. In the ideal world I would be returned to the R prompt,
but it isn't overly critical in this application since it is being run
more or less headless as is.

The other problem, which makes me cringe of course, is that this is all
further complicated by the fact that it is not just C, but C++ and running
on Win64 ;-)   I tried not to mention that of course ...

Your insights are very appreciated, and I now have further knowledge into
making this work in other applications, but my hope for this one is
dwindling.

Best,
Jeff


On 5/23/12 11:49 AM, Simon Urbanek simon.urba...@r-project.org wrote:


On May 23, 2012, at 12:40 PM, Jeffrey Ryan wrote:

 Simon,
 
 Thanks for the clarifying example.  I fear my current set up fails the
 test for 'no R calls',

Well, but in that case you already have interrupt points so I'm not sure
what is the problem? I thought the whole point is that you have long
processing in some 3rd party library where you can't call R API so that's
why you need the hack in the first place ...


 so I think I am stuck on the ugly variant for my
 current challenge, but I will be able to use this in other places.
 
 Thanks again,
 Jeff
 
 On 5/22/12 4:45 PM, Simon Urbanek simon.urba...@r-project.org wrote:
 
 Jeff,
 
 On May 22, 2012, at 4:31 PM, Jeffrey Ryan wrote:
 
 I have a continuous loop running in an external library that I am
 calling
 from C (R API).  This loop is processing events in real time with the
 possibility of significant lag between events.
 
 When processing an event, I can make use of R_CheckUserInterrupt, but
 while the external library code is waiting on a new event, I don't
have
 an
 opportunity to call this - my entry points are only on events.
 
 
 Assuming that while in the library there are no R calls (important!),
you
 can use setjmp/longjmp to branch your code depending on whether you
raise
 an interrupt or not (see below). This also makes sure that you process
 things on the R side properly
 
 Another alternative is to run your library call on a separate thread
and
 have R wait for the result. In that case you don't need to mess with
 interrupts since your library code will run separately from R. The
 downside is that you need to mess with threads which may or may not be
an
 issue depending on the complexity of your code and whether you want it
to
 be cross-platform or not.
 
 Cheers,
 Simon
 
 
 Example code:
 
 #include signal.h
 #include setjmp.h
 #include unistd.h
 
 #include Rinternals.h
 #include R_ext/GraphicsEngine.h /* only needed if you use
 R_interrupts_pending */
 
 static jmp_buf jenv;
 
 static void my_int(int sig) {
 longjmp(jenv, 1); /* this also restores the interrupt handlers */
 }
 
 SEXP my_R_function(...) {
 
 if (setjmp(jenv) == 0) { /* enter your protected code */
 void (*old_sig)(int);
 old_sig = signal(SIGINT, my_int);
 /* call your library here */
 /* restore original INT handler */
 signal(SIGINT, old_sig);
 } else { /* this will get called on interrupt */
 /* you can do what you want - you're back to R-safe code here, so you
 can either raise an error or return from your function */
 /* if you want to trigger regular R interrupt handling, use this: */
  R_interrupts_pending = 1;
  R_CheckUserInterrupt();
 /* the above should not return */
 }
 
 
 
 I can capture a SIGINT by redefining signal(SIGINT, myhandler) before
 calling the lib, but I am somewhat at a loss in terms of what I can do
 within the handler that would let me pass control back to R.
 
 void myhandler (int s) {
 error(interrupt caught!);
 }
 
 Works, but I am sure it isn't supposed to.  In fact I know 

Re: [Rd] Capturing signals from within external libs

2012-05-22 Thread Simon Urbanek
Jeff,

On May 22, 2012, at 4:31 PM, Jeffrey Ryan wrote:

 I have a continuous loop running in an external library that I am calling
 from C (R API).  This loop is processing events in real time with the
 possibility of significant lag between events.
 
 When processing an event, I can make use of R_CheckUserInterrupt, but
 while the external library code is waiting on a new event, I don't have an
 opportunity to call this - my entry points are only on events.
 

Assuming that while in the library there are no R calls (important!), you can 
use setjmp/longjmp to branch your code depending on whether you raise an 
interrupt or not (see below). This also makes sure that you process things on 
the R side properly

Another alternative is to run your library call on a separate thread and have R 
wait for the result. In that case you don't need to mess with interrupts since 
your library code will run separately from R. The downside is that you need to 
mess with threads which may or may not be an issue depending on the complexity 
of your code and whether you want it to be cross-platform or not.

Cheers,
Simon


Example code:

#include signal.h
#include setjmp.h
#include unistd.h

#include Rinternals.h
#include R_ext/GraphicsEngine.h /* only needed if you use 
R_interrupts_pending */

static jmp_buf jenv;

static void my_int(int sig) {
  longjmp(jenv, 1); /* this also restores the interrupt handlers */
}

SEXP my_R_function(...) {

if (setjmp(jenv) == 0) { /* enter your protected code */
  void (*old_sig)(int);
  old_sig = signal(SIGINT, my_int);
  /* call your library here */
  /* restore original INT handler */
 signal(SIGINT, old_sig);
} else { /* this will get called on interrupt */
  /* you can do what you want - you're back to R-safe code here, so you can 
either raise an error or return from your function */
  /* if you want to trigger regular R interrupt handling, use this: */
   R_interrupts_pending = 1;
   R_CheckUserInterrupt();
  /* the above should not return */
}



 I can capture a SIGINT by redefining signal(SIGINT, myhandler) before
 calling the lib, but I am somewhat at a loss in terms of what I can do
 within the handler that would let me pass control back to R.
 
 void myhandler (int s) {
  error(interrupt caught!);
 }
 
 Works, but I am sure it isn't supposed to.  In fact I know it is wrong,
 since after interrupting once SIGINTs are subsequently ignored, even if I
 reset the signal to the original one (as returned by the first call to
 signal).
 
 Currently I can exit(1) of course, but that is tragically bad form IMO,
 though will work in my situation.
 
 In short, what is the proper way to handle SIGINT in external code that is
 called from R, that allows R to handle the signal.  Thoughts or
 suggestions appreciated.
 
 Thanks,
 Jeff
 
 __
 R-devel@r-project.org mailing list
 https://stat.ethz.ch/mailman/listinfo/r-devel
 
 

__
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel