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.urba...@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.urba...@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 > > ______________________________________________ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel