From: Daniel J S. <dan...@ie...> - 2004-01-09 22:32:24
|
Arnd Baecker wrote: >Hi, > >On Wed, 7 Jan 2004, Ethan Merritt wrote: > > > >>On Wednesday 07 January 2004 15:54, Ethan Merritt wrote: >> >> >>>if we are going to >>>switch to unbuffered mode we should first make sure the >>>buffer is empty, or else store it elsewhere for later execution. >>> >>>I don't yet see a trivial way of doing this, but ... >>> >>> >>Trivial indeed. I was focused on the "or else", but in fact >>the first alternative is the easy one. The buffer is empty >>when the program starts, so I moved the call to setvbuf() >>out of X11_init() and put it right at the start of plot.c where >>the other I/O streams are being initialized. >> >>The X11 paste buffer is now working, and piping through awk >>now works too. I left the call to setvbuf() protected by >>#ifdef X11 but I doubt that it needs to be. Are any non-X11 >>platforms also suffering lost characters in the input stream? >> >> > >Well, for me the picture is slightly different: > a) on a PIV machine: no problems, pasting works, piping works > b) on my PIII (which I used to do the testing): > - pasting does not work the first time > - piping seems to work fine now > > I haven't done thorough testing yet, but this seems > to improve! > > From Hans: > I suspect we'll have to avoid stdin buffering and possibly blocking > I/O altogether. I.e. don't switch off buffering halfway into the program, > but immediately after startup, before the first character is read. From Arnd: >Is the pasting problem related with what Hans just wrote/suggested >"I.e. don't switch off buffering halfway into the program, but >immediately after startup"? >((Speculating: maybe a "fast" machine is fast enough to switch off >buffering before something is written to the buffer?)) > I wonder if there is any way of avoiding a race from the level of Gnuplot. If you turn off buffering immediately after startup, what if a number of Gnuplot commands are already in the buffer? (Sounds like a plausible situation.) Then the commands will be lost. Simply tossing out what is in the buffer of course won't do. It seems to me that resolving the race condition can only be done at a low level. Thus the only way to resolve the race condition, in one form or another from Gnuplot, is for there to be an ability for the "setvbuf" command to return the contents of the buffer right before it was changed. Then one would have to reconstruct the input stream by storing that somewhere. You can't store what is currently in the buffer then set the I/O stream to non-buffered as two independent actions. Something could enter the I/O buffer in that time between the save and the set, for multitasking systems, and again characters will be lost. Only the low level routines can protect the buffer from something new being entered. Right? I think the best solution here is to keep the two input streams independent. Leave the keyboard stream as it is, no "setvbuf". Create different pipes for the mouse (that can later be configured), I contend. That means that upon creating an X11 plot window a pipe ID of some sort is passed to gnuplot_x11. Create a variable in the plot structure of gnuplot_x11 and save that pipe ID in there and whenever there is a mouse action for that window, send its primitive mouse information out that pipe. Whatever is on the other end of the pipe interprets the mouse commands. The default handler on the gnuplot side is to reissue the "replot" command if appropriate. Be consistent with who creates and deletes the pipes. Probably gnuplot should create the pipes and gnuplot_x11 should be the one to delete them. (That way, gnuplot_x11 will never be sending data to a defunct pipe. Note, it doesn't need to be Gnuplot that creates the pipe ID. Perhaps a higher application could create the pipe and give a pipe ID as an argument to the "set term x11" command.) From the gnuplot_x11 side of things it is fairly straightforward. The work lies on the gnuplot side of things: 1) Fix up the I/O scheme so that gnuplot doesn't wait on keyboard input. Whenever keyboard input is available then parse it. 2) A system for interpreting primitives coming across the various "mouse pipes"... or can I take the liberty of being ultra-silly here and coin the phrase "mouse holes", or better still "mouse traps" :) ... Seriously, it would involve a mechanism for keeping track of the pipes, a linked-list sort of thing for the default handler. Or an alternative would be one mouse hole (sick of this phrase already?) and the primitive info would include a plot number along with it. [I'd prefer a linked list of connections, myself.] 3) Since gnuplot only has a "current plot" replot and not information for all its plots, there needs to be some variable that keeps track of which plot number corresponds with the "current plot" replot info. That way, the "replot" command can be reissued when the window number and the replot info match. It sounds like a lot of work, but I don't think it is IMHO. Linked lists are fairly straightforward, especially when they are so simple. Putting effort into a new scheme seems wiser to me than attempting to resolve the race condition. Are there unforeseen problems with losing primitives in the pipe somehow? I don't know. Any thoughts anyone? Is keeping the mouse and keyboard separate a necessity? Dan |