From simon.urbanek at r-project.org  Sun Dec 16 04:49:18 2012
From: simon.urbanek at r-project.org (Simon Urbanek)
Date: Sat, 15 Dec 2012 22:49:18 -0500
Subject: [Rd] Could Rstd_Busy do something (src/unix/sys-std.c)?
In-Reply-To: <CAGBu4CONPpAh2T=3mzGLf9TEgDCW-3P4x2WKeD76FXV44srspg@mail.gmail.com>
References: <CAGBu4CNTtEcBEA6yB5tM8JkEDdVyTAr2xC+75Ay+dFM30=BTMg@mail.gmail.com>
	<CDB0FA0A-94E8-4BFA-961F-4ADA4ED04A2F@r-project.org>
	<CAGBu4CPT_wK5xjdFxX0WrF=TxiS8-7zYENZ6FP=XkYVo41yyRg@mail.gmail.com>
	<77436EA2-B617-4267-9694-B1CCB35FF4B2@r-project.org>
	<CAGBu4CONPpAh2T=3mzGLf9TEgDCW-3P4x2WKeD76FXV44srspg@mail.gmail.com>
Message-ID: <954366D2-3EC2-43B3-ABB9-16490F011370@r-project.org>


On Dec 15, 2012, at 5:32 PM, Jakson Alves de Aquino wrote:

> On Sat, Dec 15, 2012 at 5:41 PM, Simon Urbanek
> <simon.urbanek at r-project.org> wrote:
>> 
>> On Dec 15, 2012, at 2:20 PM, Jakson Alves de Aquino wrote:
>> 
>>> On Sat, Dec 15, 2012 at 1:09 PM, Simon Urbanek
>>> <simon.urbanek at r-project.org> wrote:
>>>> On Dec 15, 2012, at 6:36 AM, Jakson Alves de Aquino wrote:
>>>>> I could avoid the crash if I knew that R is busy at the moment that
>>>>> it receives the SIGWINCH. Thus my question is: Could Rstd_Busy()
>>>>> set the value of a variable so packages like setwidth could know
>>>>> that R is busy?
>>>> 
>>>> You're looking at the wrong spot - the Busy callback is meant for UI
>>>> signaling that R may enter a longer time of processing, it is not
>>>> really an indicator that R is busy - R can be busy even without the
>>>> busy state being signaled.
> [...]
>>>> The other way is to register an input handler and signal your FD
>>>> when you get SIGWINCH, that guarantees that your handler will be
>>>> called as soon as possible after the signal has arrived - that is
>>>> probably what you want (see CarbonEL for a simple example how this
>>>> is used).
>>> 
>>> Based on CarbolEL, I added the following to setwidth_Start() function:
>>> 
>>>   int fds[2];
>>>   if(pipe(fds))
>>>       Rprintf("pipe > 0\n");
>>>   else
>>>       Rprintf("pipe = 0\n");
>>>   ifd = fds[0];
>>>   ofd = fds[1];
>>>   addInputHandler(R_InputHandlers, ifd, &uih, 32);
>>> 
>>> And, also based on CarbolEL, I created the following uih() function:
>>> 
>>>   static void uih(void *data) {
>>>     char buf[16];
>>> 
>>>     if(read(ifd, buf, 16) == 0){
>>>         Rprintf("read = 0 :: %s\n", buf);
>>>         Rprintf("%d written\n", write(ofd, buf, 16));
>>>     } else {
>>>         Rprintf("read != 0\n");
>>>     }
>>>   }
>>> 
>>> However, the uih() function never gets called.
>>> 
>> 
>> You didn't provide the signal yet - you have the initialization and
>> receiving end ready - now you need to write the piece that triggers
>> the input.
> 
> It works like a charm now. If handle_winch() is called a hundred times
> while R is busy, uih() will also be called a hundred times, but only
> when R is no longer busy:
> 

Note that you're not using the payload of the pipe at all, so you could simply just send a single byte (not that it matters but you don't need the 16-byte packets).

Also you don't want to send anything if the signal is already enqueued, it's pointless to try to send more (you could clog the pipe), so simply use a flag that you set on write and reset it on read -- if that flag is set you don't write anything. That will make sure that you get only one trigger even if more signals arrived while R is busy.  Everything is synchronous here so no need to worry.

Finally, I wouldn't mess with the signal all the time - just keep it active without touching it and use a flag to avoid re-entrance if you really think it's necessary.

Cheers,
Simon



>    void handle_winch(int sig){
>        signal(SIGWINCH, SIG_IGN);
>        char buf[16];
>        *buf = 0;
>        if(write(ofd, buf, 16) <= 0)
>            REprintf("setwidth error: write <= 0\n");
>        signal(SIGWINCH, handle_winch);
>    }
> 
>    static void uih(void *data) {
>      char buf[16];
>      if(read(ifd, buf, 16) == 0)
>          REprintf("setwidth error: read = 0\n");
>      R_ToplevelExec(setwidth_Set, NULL);
>    }
> 
> I added the if(read()) and if(write()) to avoid compiler warnings
> about return values not being used.
> 
> Thank you very much!
> 
> -- 
> Jakson Alves de Aquino
> Federal University of Cear?
> Social Sciences Department
> www.lepem.ufc.br/aquino.php
> 
> 



[Rd] Could Rstd_Busy do something (src/unix/sys-std.c)?
Simon Urbanek