From: Mojca M. <moj...@gm...> - 2014-02-13 11:07:56
|
On Thu, Feb 13, 2014 at 5:56 AM, sfeam wrote: > > Based on this and our off-line back and forth debugging, I am pretty > sure that the attached patch will fix your problem that the first plot > is not drawn. It does fix the first plot, but not the first plot after I close a qt window. Here's what I get: Terminal type set to 'qt' gnuplot> plot x # OK -> resizing gnuplot> plot x # OK (but why resizing?) gnuplot> -> resizing gnuplot> plot x # OK gnuplot> plot x # OK gnuplot> # close the window gnuplot> plot x # NOT SHOWN gnuplot> plot x # OK (but why resizing twice?) -> resizing gnuplot> -> resizing gnuplot> The logic is still wrong. Mojca |
From: Mojca M. <moj...@gm...> - 2014-02-10 11:21:53
|
On Mon, Feb 10, 2014 at 1:57 AM, sfeam wrote: > On Sunday, 09 February 2014 12:29:34 PM Mojca Miklavec wrote: >> On Sun, Feb 9, 2014 at 12:11 PM, Mojca Miklavec wrote: >> >> According to a gdb a lot of that "infinite cycling" (when not properly >> connected) happens with >> >> while (!receivedFontPropos) >> qt->socket.waitForReadyRead(1000); >> while (qt->socket.bytesAvailable() >= (int)sizeof(gp_event_t)) >> } > > It should not be possible for that while {} construction to gobble CPU. > It only wakes up and checks the socket once per second. > Unless (which I'm beginning to suspect) all the 1000 msec timeouts > are acting as NOOPs on OSX. Could it really be that Qt on OSX > doesn't implement event-driven waits? Sorry, I don't know the answer to that, but I can do some quick-and-dirty test if you can suggest me what to test. But in my opinion the problem is that qt isn't properly initialized by the time it executes the "problematic" part of the code. >> And indeed if I change the timeout: >> >> --- a/src/qtterminal/qt_term.cpp >> +++ b/src/qtterminal/qt_term.cpp >> @@ -251,7 +252,7 >> >> // The QLocalSocket::waitForConnected does not respect the >> time out argument when the >> // gnuplot_qt application is not yet started. To wait for it, >> we need to implement the timeout ourselves >> - QDateTime timeout = QDateTime::currentDateTime().addMSecs(1000); >> + QDateTime timeout = QDateTime::currentDateTime().addMSecs(10000); >> do >> { >> qt->socket.connectToServer(server); >> >> it suddenly almost starts working. I'm saying almost because the first >> plot doesn't work, but the second one does. > > Hence my suspicion that timeouts < 1000msec are not working. > I suggest you do a global search and replace for timeouts and make > sure they are all >1000 msec. I'm not sure how to search for all timeouts. I need some help with that. I see the following (but I'm not sure how to change it): if (options == TERM_ONLY_CHECK_MOUSING) { timeout = &one_msec; one_msec.tv_sec = 0; one_msec.tv_usec = TERM_EVENT_POLL_TIMEOUT; } and I'm not sure how to reliable find all the others. > Finally a trace that makes sense in that it involves a recent change. > This bit belongs to the patch: > > 2014-01-26 Jérôme Lodewyck <lod...@us...> > > * src/qtterminal/qt_term.cpp: Implement font metric caching. This solves > a flickering issue when a large number of font changes are called (for > example when rotating the world plot in world2.dem). > > * src/qtterminal/QtGnuplotInstance.*: New public function that sends a > command to gnuplot and blocks until it receives the answer. > > Can you back out just that one set of changes from current CVS and see > if that makes your qt terminal work? If I go back to the following version ... Date: Sat Jan 18 21:30:19 2014 +0000 interactive color character art terminal using libcaca (I didn't try to revert just a single commit, I simply went back to the version before the one you claimed to be problematic.) ... then gnuplot doesn't get stuck at 99% CPU any longer. It returns back to accepting input and the second plot works fine. (But please note that this isn't really a problem as long as timeouts are sufficiently large. I didn't check, but I suspect that the infinite loop happens just because Qt isn't properly initialized at the time when the code is trying to do something.) Just to make it clear. The following happens: Terminal type set to 'qt' gnuplot> plot sin(x) # too short timeout, so another gnuplot_qt is started Could not connect gnuplot_qt "" . Starting a new one # starts a new gnuplot_qt, but timeouts are still too short, so nothing can be seen gnuplot> plot cos(x) # the first plot that works ok gnuplot> quit # only closes the second gnuplot_qt, one gnuplot_qt needs to be closed manually Independent on the font patch (which may not necessarily be bad, I didn't check) the following are the main issues from my point of view: 1.) The following part of the code: while((qt->socket.state() != QLocalSocket::ConnectedState) && (QDateTime::currentDateTime() < timeout)); // Still not connected... if ((qt->socket.state() != QLocalSocket::ConnectedState) && retry) gives up too soon (1000 ms seems too short) and simply opens a new "gnuplot_qt". This is a problem also because the old gnuplot_qt never gets closed as a consequence. But this can be easily fixed by increasing the timeout, at least the majority of problems would go away. 2.) The second time when the same code gets executed (with retry=false), it gives up too soon again. But now the problem is that gnuplot blindly assumes that the code succeeded and connection is alive. In my opinion there should be another check at the end of qt_connectToServer (or somewhere else): if (qt->socket.state() != QLocalSocket::ConnectedState)) that would throw an error and prevent Qt from proceeding in case that connection didn't succeed. Gnuplot shouldn't blindly assume that connection succeeded the second time it tried. Curiously, gnuplot_qt has about 40 font files open when I run just "plot sin(x)". I don't understand why. For example: /Library/Fonts/STIXIntSmReg.otf /Library/Fonts/STIXSizThreeSymBol.otf /Library/Fonts/STIXSizFiveSymReg.otf /Library/Fonts/Microsoft/Marlett.ttf /Library/Fonts/STIXSizOneSymBol.otf /Library/Fonts/STIXSizFourSymReg.otf /Library/Fonts/STIXSizFourSymBol.otf /Library/Fonts/STIXIntUpSmReg.otf /Library/Fonts/STIXSizThreeSymReg.otf /Library/Fonts/STIXSizOneSymReg.otf /Library/Fonts/STIXVar.otf /Library/Fonts/STIXIntUpBol.otf /Library/Fonts/STIXSizTwoSymReg.otf /System/Library/Fonts/Symbol.ttf /Library/Fonts/Microsoft/MS Reference Specialty.ttf /Library/Fonts/Microsoft/Bookshelf Symbol 7.ttf /Library/Fonts/STIXIntDReg.otf /Library/Fonts/STIXNonUniBolIta.otf /System/Library/Fonts/Apple Braille Pinpoint 8 Dot.ttf /System/Library/Fonts/Apple Braille Outline 8 Dot.ttf /Library/Fonts/STIXIntUpReg.otf /System/Library/Fonts/ZapfDingbats.ttf /Library/Fonts/STIXNonUniIta.otf /Library/Fonts/STIXIntUpDBol.otf /Library/Fonts/Hoefler Text Ornaments.ttf /Library/Fonts/STIXNonUni.otf /Library/Fonts/Bodoni Ornaments ITC TT/..namedfork/rsrc /Library/Fonts/STIXNonUniBol.otf /System/Library/Fonts/Apple Braille Outline 6 Dot.ttf /Library/Fonts/STIXIntUpSmBol.otf /System/Library/Fonts/Apple Braille Pinpoint 6 Dot.ttf /System/Library/Fonts/Apple Color Emoji.ttf /Library/Fonts/STIXIntSmBol.otf /Library/Fonts/STIXSizTwoSymBol.otf /Library/Fonts/STIXIntDBol.otf /Library/Fonts/Type Embellishmnt One LET/..namedfork/rsrc /System/Library/Fonts/Apple Braille.ttf /System/Library/Fonts/LucidaGrande.ttc ---------------------- In summary. If I do both: (a) revert to the version from Sat Jan 18 21:30:19 2014 (b) increase QDateTime timeout = QDateTime::currentDateTime().addMSecs(10000); then gnuplot works fine. If I do just (b) on the latest version, then the first plot fails. If I do just (a), the first plot fails, a second "gnuplot_qt" is started (which is bad) and the second plot succeeds. Mojca |
From: Mojca M. <moj...@gm...> - 2014-02-10 11:37:29
|
Also, now that there is no more forking involved, please delete src/qtterminal/qt_term_mac.m as well as the corresponding lines in Makefiles. Unless you plan to switch back to forking, the file is luckily no longer needed. It was only used to hide a non-functional qt window in the background (and didn't even work on Mac OS X <= 10.6 or with Qt 5). With the current approach that window/process is no longer present. Mojca |
From: sfeam <sf...@us...> - 2014-02-10 16:49:40
|
On Monday, 10 February 2014 12:37:23 PM Mojca Miklavec wrote: > Also, now that there is no more forking involved, please delete > src/qtterminal/qt_term_mac.m > as well as the corresponding lines in Makefiles. The program still forks. The only change is that fork() is perforned via a Qt library routine rather than being invoked in-line. Ethan > > Unless you plan to switch back to forking, the file is luckily no > longer needed. It was only used to hide a non-functional qt window in > the background (and didn't even work on Mac OS X <= 10.6 or with Qt > 5). With the current approach that window/process is no longer > present. > > Mojca > > ------------------------------------------------------------------------------ > Managing the Performance of Cloud-Based Applications > Take advantage of what the Cloud has to offer - Avoid Common Pitfalls. > Read the Whitepaper. > http://pubads.g.doubleclick.net/gampad/clk?id=121051231&iu=/4140/ostg.clktrk > _______________________________________________ > gnuplot-beta mailing list > gnu...@li... > Membership management via: https://lists.sourceforge.net/lists/listinfo/gnuplot-beta |
From: Mojca M. <moj...@gm...> - 2014-02-10 23:39:31
Attachments:
dock.patch
|
On Mon, Feb 10, 2014 at 5:51 PM, sfeam wrote: > On Monday, 10 February 2014 12:37:23 PM Mojca Miklavec wrote: >> Also, now that there is no more forking involved, please delete >> src/qtterminal/qt_term_mac.m >> as well as the corresponding lines in Makefiles. > > The program still forks. The only change is that fork() is perforned via > a Qt library routine rather than being invoked in-line. Nonetheless that doesn't change my request to remove that code. Even if forking is still present, it is now apparently done in such a way that it doesn't confuse Qt any longer. I'm attaching a patch. It nearly reverts the following commit: 2012-06-23 Jérôme lodewyck <lod...@us...> * configure.in src/Makefile.am src/qtterminal/qt_term.cpp src/qtterminal/qt_term_mac.m: Proper handling of the qt terminal dock icons on Mac OS (I'm saying nearly because some of the changes were already present in the commit from 2012-01-17.) The whole point of that code (mostly requested by me) was an ugly workaround for problems related to the way forking was previously implemented. I can do more testing, but it looks as if that particular problem is gone. Mojca |
From: sfeam <sf...@us...> - 2014-02-12 07:22:43
|
On Tuesday, 11 February 2014 10:15:24 PM Thomas Bleher wrote: > * Ethan A Merritt <sf...@us...> [2014-02-11 21:35]: > > > To see why, change it to this: > > qDebug() << "qt_connectToServer " << server; > > do > > { > > qt->socket.connectToServer(server); > > if (!qt->socket.waitForConnected(TIMEOUT)) > > qDebug() << qt->socket.errorString(); > > usleep(50000); > > } > > while(...) > > > > Regardless of the value of TIMEOUT, including -1 or blank, the > > waitForConnected returns immediately with an error: > > "QLocalSocket::connectToServer: Invalid name" > > [Note: I haven't looked at this in detail, so these are just my guesses] > > I think the error is probably a race condition: > - gnuplot starts the external gnuplot_qt process > - Immediately afterwards it tries to connect to the socket from > gnuplot_qt > - Depending on scheduling, gnuplot_qt may have had a chance to run or > not. But in any case it needs to do some initialization first. > > So my guess is that the "Invalid name" error stems from the fact that > during the first iteration of the loop, the named pipe (which is created > by gnuplot_qt) is simply not there yet. That makes sense, but the first attempt to connect _always_ fails, even if I explicitly wait for several seconds before invoking waitForConnected(). So I think it's not just a timing race. There's something that doesn't get initialized until the first connection attempt. So the first attempt fails but then the next attempt succeeds. I have gone ahead and placed a variant of that modification into CVS. I think the worst it can do is hang a session that was going to fail anyhow. We can still fix the source of the initial failure if we ever find it. > I also looked through the recent changes to the gnuplot code just now, > and noticed that no QApplication object is created anymore in gnuplot. > According to the docs, waitForConnected() should also work without an > event loop, but I think it would still be interesting to see if the high > CPU usage goes away if QCoreApplication is replaced by QApplication. > Just my 2cents. > Thomas I don't see any difference here, but then I wasn't seeing CPU-churning to begin with. Let's see what the Windows/OSX people report. Ethan > > > Without the usleep() it spews hundreds or even thousands of these errors > > before fallling through to the rest of the code. The usleep reduces this > > to a manageable number of error reports. > > So the first connection attempts always fail, even under linux, and the > > failure is immediate. > > Why is it an invalid name? I don't know. > > How does it eventually succeed? I don't know that either. > > > > Since TIMEOUT is ignored this is becomes a CPU-burning loop, > > which is what Mojca originally reported. The usleep should fix that, and a > > large enough manual timeout as in > > QDateTime timeout = QDateTime::currentDateTime().addMSecs(30000); > > may in fact be necessary. But it would be nice to understand the real > > reason why the initial connection attempts fail, because maybe we can > > test and wait on that condition directly and avoid the useless loop here. > > > > Ethan |
From: Daniel J S. <dan...@ie...> - 2014-02-12 08:20:24
|
On 02/12/2014 01:25 AM, sfeam wrote: > On Tuesday, 11 February 2014 10:15:24 PM Thomas Bleher wrote: >> * Ethan A Merritt<sf...@us...> [2014-02-11 21:35]: >> >>> To see why, change it to this: >>> qDebug()<< "qt_connectToServer "<< server; >>> do >>> { >>> qt->socket.connectToServer(server); >>> if (!qt->socket.waitForConnected(TIMEOUT)) >>> qDebug()<< qt->socket.errorString(); >>> usleep(50000); >>> } >>> while(...) >>> >>> Regardless of the value of TIMEOUT, including -1 or blank, the >>> waitForConnected returns immediately with an error: >>> "QLocalSocket::connectToServer: Invalid name" >> >> [Note: I haven't looked at this in detail, so these are just my guesses] >> >> I think the error is probably a race condition: >> - gnuplot starts the external gnuplot_qt process >> - Immediately afterwards it tries to connect to the socket from >> gnuplot_qt >> - Depending on scheduling, gnuplot_qt may have had a chance to run or >> not. But in any case it needs to do some initialization first. >> >> So my guess is that the "Invalid name" error stems from the fact that >> during the first iteration of the loop, the named pipe (which is created >> by gnuplot_qt) is simply not there yet. > > That makes sense, but the first attempt to connect _always_ fails, > even if I explicitly wait for several seconds before invoking waitForConnected(). > So I think it's not just a timing race. There's something that doesn't > get initialized until the first connection attempt. So the first attempt fails > but then the next attempt succeeds. > > I have gone ahead and placed a variant of that modification into CVS. > I think the worst it can do is hang a session that was going to fail anyhow. > We can still fix the source of the initial failure if we ever find it. > >> I also looked through the recent changes to the gnuplot code just now, >> and noticed that no QApplication object is created anymore in gnuplot. >> According to the docs, waitForConnected() should also work without an >> event loop, but I think it would still be interesting to see if the high >> CPU usage goes away if QCoreApplication is replaced by QApplication. >> Just my 2cents. >> Thomas > > I don't see any difference here, but then I wasn't seeing CPU-churning > to begin with. Let's see what the Windows/OSX people report. > > Ethan Here looks like a potential bug: // Called before a plot to connect to the terminal window, if needed void qt_connectToServer() { if (!qt) return; ensureOptionsCreated(); // Determine to which server we should connect bool connectToWidget = !qt_option->Widget.isEmpty(); QString server = connectToWidget ? qt_option->Widget : qt->localServerName; if (qt->socket.state() == QLocalSocket::ConnectedState) { // Check if we are already connected to the correct server if (qt->socket.serverName() == server) return; // Otherwise disconnect qt->socket.disconnectFromServer(); while (qt->socket.state() == QLocalSocket::ConnectedState) qt->socket.waitForDisconnected(1000); } // Start the gnuplot_qt helper program if not already started if (!connectToWidget && !qt->gnuplot_qtStarted) execGnuplotQt(); // Connect to the server, or local server if not available. qt_connectToServer(server); } At the top of this function is: QString server = connectToWidget ? qt_option->Widget : qt->localServerName; Potentially, localServerName could be an empty string or some valid server name. If localServerName happens to be empty, it's probably because the server wasn't connected yet or there was an error in connecting. If that is the case then this test will be true: // Start the gnuplot_qt helper program if not already started if (!connectToWidget && !qt->gnuplot_qtStarted) execGnuplotQt(); But, inside execGnuplotQt() is where the name of qt->localServerName is set, so if this line executed "server" will no longer be pertinent. Perhaps the first time through "server" is empty and after the valid qtgnuplot#### is made the code is requesting for a server with empty string. Perhaps the code should be more along the lines: // Start the gnuplot_qt helper program if not already started if (!connectToWidget && !qt->gnuplot_qtStarted) { execGnuplotQt(); server = qt->localServerName; } if (!server.isEmpty()) { // Connect to the server, or local server if not available. qt_connectToServer(server); } That isn't very well organized either. Dan |
From: Mojca M. <moj...@gm...> - 2014-02-12 19:43:18
|
On Wed, Feb 12, 2014 at 8:25 AM, sfeam wrote: > > I have gone ahead and placed a variant of that modification into CVS. /.../ > Let's see what the Windows/OSX people report. With the latest version from trunk the second plot works fine. The first plot doesn't work at all, so there are apparently more fixes needed. Given the large amount of different suggestion I'm not exactly sure what I should try. (Something is telling me that Dan is right about signals and slots, but I'm not sure how to implement that.) Which version of gnuplot will have the new qt functionality/patches (= the code that we are discussing about)? Mojca PS: I would be grateful if the patch for TransformProcessType on OS X would be applied before the sources start diverting too much and one would need to create the patch again. |
From: Ethan A M. <sf...@us...> - 2014-02-14 19:48:40
|
On Saturday, 08 February, 2014 03:01:09 Mojca Miklavec wrote: > Yes. I'm using 4.8.5. (Unfortunately the maintainer of Qt 4 gave up on > Qt 5 for some reason – apparently too much work and too many problems > when he tried to create a package and nobody else is willing to step > in. But I did successfully link gnuplot against a different Qt > installation and I could try to repeat that now to check whether > current solution works in 5.2. Can you try with the "official" Qt-for-OSX package? http://qt-project.org/doc/qt-5/macosx.html If that works, we can simply recommend that people use it rather than fighting with 3rd-party packages. Ethan |
From: Mojca M. <moj...@gm...> - 2014-02-14 20:26:48
|
On Fri, Feb 14, 2014 at 8:46 PM, Ethan A Merritt wrote: > On Saturday, 08 February, 2014 03:01:09 Mojca Miklavec wrote: > >> Yes. I'm using 4.8.5. (Unfortunately the maintainer of Qt 4 gave up on >> Qt 5 for some reason – apparently too much work and too many problems >> when he tried to create a package and nobody else is willing to step >> in. But I did successfully link gnuplot against a different Qt >> installation and I could try to repeat that now to check whether >> current solution works in 5.2. > > Can you try with the "official" Qt-for-OSX package? > > http://qt-project.org/doc/qt-5/macosx.html I definitely plan to test gnuplot with Qt 5, but ... > If that works, we can simply recommend that people use it > rather than fighting with 3rd-party packages. And start fighting with instructions on how to compile gnuplot and octave on their own? Esp. because it's probably not exactly trivial to configure gnuplot to find the Qt headers and libraries. And I would not even attempt to use octave if I had to compile it myself. Qt 5 isn't supported in MacPorts (lack of manpower to port the complex package), I don't find it in Fink either. And while HomeBrew provides Qt 5, gnuplot links against Qt 4 there as well. And no gnuplot developer is creating binary packages with gnuplot for Mac. So basically all the package managers are currently using Qt 4 for gnuplot. Asking users to compile gnuplot (and Octave) themselves just to work around a bug ... sounds a bit nasty. Mojca |
From: Daniel J S. <dan...@ie...> - 2014-02-16 23:48:05
|
On 02/12/2014 08:50 PM, Daniel J Sebald wrote: > On 02/12/2014 02:49 PM, Thomas Bleher wrote: >> * Daniel J Sebald<dan...@ie...> [2014-02-12 06:36]: >>> In any case, I suggest adding the sleep as Ethan has done. There is >>> no reason that should be running at 100%. In fact, there is >>> probably a preferred way to do this without polling loops. I >>> learned a little bit about Qt working on Octave and Qt has this >>> paradigm of signals and slots and the developers suggest adhering to >>> the concept otherwise can get kind of dodgy (not in this simple >>> case...but cases where widget IDs are floating about). >>> >>> signal: something that a Qt object emits >>> slot: the destination of the signal which can >>> be of any number, e.g., five other >>> objects could connect a slot to a signal >>> >>> Anyhow, I don't have time to look at this right now, but if one >>> looks at the documentation for a Qt socket: >>> >>> http://qt-project.org/doc/qt-4.8/qlocalsocket.html#connectToServer >>> >>> it indicates that a signal is emitted when the connection is >>> complete and there is a signal emitted when there is an error. So >>> the proper thing to do is to first make connections to the socket >>> sort of like the following ("success" and "failed" are custom member >>> functions): >>> >>> connect (createdsocket, SIGNAL (connected ()), watcher, SLOT (success ())); >>> connect (createdsocket, SIGNAL (error ()), watcher, SLOT (failed ())); >>> >>> and then tell the socket to attempt to connect to the server: >>> >>> createdsocket->connectToServer (name) >>> >>> There is no need to check in a loop for anything. Either the socket >>> will successfully connect and emit "connected" at which point >>> "success()" will get called or the socket will timeout and emit >>> "error" at which point "failed()" will get called. >>> >>> One can get very creative about connections made, the number of >>> slots watching a signal, doing this dynamically, etc. So instead of >>> a recursive routine, it might be multiple connections, or >>> dynamically reconnect/disconnect in the "failed()" slot. Etc. >> >> signals and slots are indeed very nice, but they need a Qt event loop to >> work correctly. I don't think it is possible to add the Qt event loop to >> gnuplot without major surgery. (Well, you can start a local event loop >> using QEventLoop inside a function, but in this case it's just more work >> to get the same result we already have). > > Good point, but we'll see if we can make it work somehow. It's worth at > least a couple hours time to test whether it is feasible. It would seem > that the place to start the Qt event loop along with setting up initial > signals/slots would be upon calling "term qt". The good thing is that > the graphics is done in the satellite Qt program. The bits accessible > to gnuplot core don't need graphics, so perhaps that Qt event loop could > be run in a different, non-main thread without too much work. I've a good start on the separate thread for Qt. I think it is going to work, but it will probably be next weekend until I finish. I just don't have the time right now. So Mojca, you'll have to wait a week I guess. It's been pretty straightforward up to this point. I just laid things out the way the Qt documentation shows. The separate thread starts and now timers definitely work as expected. I have signals going across without much problems. The external program gnuplot_qt shows up. There are two remaining issues: 1) Timing. Since this is signaling into a thread rather than calling, the signal returns right away and gnuplot core continues onward not having valid values for settings (i.e., x, y dimensions, etc.). While that goes on, the other thread has problems and 30 seconds later complaints show up in qDebug(), and 30 seconds later once again, and 30 seconds later is the last try. I know how to fix this. It just takes a QMutex and putting it to sleep and have the object in the QThread wake it when it has finished or timed out. I've done it before. 2) Reorganization. I think the number of ways connectToServer tries to connect can be simplified, without recursion. The complaints from Qt are along the lines of some child objects being created in a thread different from its parent. Shouldn't be difficult to fix with some better reorganization. I've already broken the Qt class declarations into individual files QtTerminalEmitter.h (same main thread as gnuplot) and QtTerminalInterface.h (separate thread), which is similar to the rest of the Qt code in the qtterminal directory. More next weekend or later in the week. Dan |
From: Daniel J S. <dan...@ie...> - 2014-02-23 03:46:29
|
On 02/22/2014 11:45 AM, Jérôme Lodewyck wrote: > I think it is fine to create the process as non-detached. We should just make > sure a new process is started (and without leaking memory) if the previous one > is killed. Oh yeah; gnuplot_qt could stop somehow. I'll watch for that. > Also, for the -persist option to work, the process should not be > deleted at exit. OK, good. I'll try to figure out how to change a QProcess to persistent. Thanks, Dan > > Jérôme > > Le samedi 22 février 2014 10:55:39 Daniel J Sebald a écrit : >> It's fairly simple, really. But first, I'd like to ask if it is alright >> to create the process not as detached, but just a normal process. Is >> that OK? If that is done, then after starting the QProcess that will >> create the local server, just wait for the process to write back the >> server's name and continue onward. By writing the local server name to >> standard output (fprint/fflush) when everything is set up and ready to >> go, the first time that qt_term attempts to connect to the local server >> will be a success. >> >> >> IN QT_TERM.CPP: >> >> if (!qtgnuplotProcess) >> qtgnuplotProcess = new QProcess(); >> qtgnuplotProcess->start(filename, QStringList()); >> if (qtgnuplotProcess->waitForStarted()) >> { >> qtgnuplotProcess->waitForReadyRead(); >> localServerName = qtgnuplotProcess->readAllStandardOutput(); >> qDebug()<< localServerName; >> } >> else >> { >> qDebug()<< "QProcess starting failed:"<< >> qtgnuplotProcess->errorString(); >> } >> >> >> IN QTGNUPLOTAPPLICATION.CPP: >> >> QtGnuplotApplication::QtGnuplotApplication(int& argc, char** argv) >> >> : QApplication(argc, argv) >> >> { >> ... >> connect(m_eventHandler, SIGNAL(disconnected()), this, >> SLOT(enterPersistMode())); >> >> fprintf(stdout, sName.toLocal8Bit().data()); >> fflush(stdout); >> } >> >> Dan > > -- Dan Sebald email: daniel(DOT)sebald(AT)ieee(DOT)org URL: http://www(DOT)dansebald(DOT)com |
From: Bastian M. <bma...@we...> - 2014-02-23 14:31:23
|
Am 23.02.2014 04:46, schrieb Daniel J Sebald: > On 02/22/2014 11:45 AM, Jérôme Lodewyck wrote: >> I think it is fine to create the process as non-detached. We should just make >> sure a new process is started (and without leaking memory) if the previous one >> is killed. > > Oh yeah; gnuplot_qt could stop somehow. I'll watch for that. > > >> Also, for the -persist option to work, the process should not be >> deleted at exit. > > OK, good. I'll try to figure out how to change a QProcess to persistent. Hhhm. I am currently unaware of a Windows API to change a process to the "detached" state. If there is indeed such a thing, this could also help to finally implement -persist properly on Windows for all interactive terminals. Bastian > > Thanks, > > Dan > > >> >> Jérôme >> >> Le samedi 22 février 2014 10:55:39 Daniel J Sebald a écrit : >>> It's fairly simple, really. But first, I'd like to ask if it is alright >>> to create the process not as detached, but just a normal process. Is >>> that OK? If that is done, then after starting the QProcess that will >>> create the local server, just wait for the process to write back the >>> server's name and continue onward. By writing the local server name to >>> standard output (fprint/fflush) when everything is set up and ready to >>> go, the first time that qt_term attempts to connect to the local server >>> will be a success. >>> >>> >>> IN QT_TERM.CPP: >>> >>> if (!qtgnuplotProcess) >>> qtgnuplotProcess = new QProcess(); >>> qtgnuplotProcess->start(filename, QStringList()); >>> if (qtgnuplotProcess->waitForStarted()) >>> { >>> qtgnuplotProcess->waitForReadyRead(); >>> localServerName = qtgnuplotProcess->readAllStandardOutput(); >>> qDebug()<< localServerName; >>> } >>> else >>> { >>> qDebug()<< "QProcess starting failed:"<< >>> qtgnuplotProcess->errorString(); >>> } >>> >>> >>> IN QTGNUPLOTAPPLICATION.CPP: >>> >>> QtGnuplotApplication::QtGnuplotApplication(int& argc, char** argv) >>> >>> : QApplication(argc, argv) >>> >>> { >>> ... >>> connect(m_eventHandler, SIGNAL(disconnected()), this, >>> SLOT(enterPersistMode())); >>> >>> fprintf(stdout, sName.toLocal8Bit().data()); >>> fflush(stdout); >>> } >>> >>> Dan >> >> > |
From: Jérôme L. <lod...@us...> - 2014-02-22 17:45:40
|
I think it is fine to create the process as non-detached. We should just make sure a new process is started (and without leaking memory) if the previous one is killed. Also, for the -persist option to work, the process should not be deleted at exit. Jérôme Le samedi 22 février 2014 10:55:39 Daniel J Sebald a écrit : > It's fairly simple, really. But first, I'd like to ask if it is alright > to create the process not as detached, but just a normal process. Is > that OK? If that is done, then after starting the QProcess that will > create the local server, just wait for the process to write back the > server's name and continue onward. By writing the local server name to > standard output (fprint/fflush) when everything is set up and ready to > go, the first time that qt_term attempts to connect to the local server > will be a success. > > > IN QT_TERM.CPP: > > if (!qtgnuplotProcess) > qtgnuplotProcess = new QProcess(); > qtgnuplotProcess->start(filename, QStringList()); > if (qtgnuplotProcess->waitForStarted()) > { > qtgnuplotProcess->waitForReadyRead(); > localServerName = qtgnuplotProcess->readAllStandardOutput(); > qDebug() << localServerName; > } > else > { > qDebug() << "QProcess starting failed:" << > qtgnuplotProcess->errorString(); > } > > > IN QTGNUPLOTAPPLICATION.CPP: > > QtGnuplotApplication::QtGnuplotApplication(int& argc, char** argv) > > : QApplication(argc, argv) > > { > ... > connect(m_eventHandler, SIGNAL(disconnected()), this, > SLOT(enterPersistMode())); > > fprintf(stdout, sName.toLocal8Bit().data()); > fflush(stdout); > } > > Dan |
From: Daniel J S. <dan...@ie...> - 2014-03-02 22:28:43
|
From thread: Re: enhanced_recursion() and do_event(), can they be redesigned? On 02/25/2014 11:39 PM, Daniel J Sebald wrote: > On 02/24/2014 09:59 AM, Jérôme Lodewyck wrote: [snip] >> Concerning the code you propose: apart from the synchronization problems >> between the Qt event loop and the main thread that you mention, I am >> worried about the performances. As far as I can see, the communication >> between the main thread and the thread running the Qt event loop relies >> on the signal/slot mechanism, which I think can be significantly slower >> that direct function calls. From rough testing, plotting a graph with a >> million points takes about 3x more time with the code you posted. [snip] > So, how about as a first step this weekend I take just the QProcess > startup code and make a nice diff/patch for you to try out and tweak how > you see fit. We'll see if that much gets us to a functioning OSX Qt > terminal. Simplifying that should clear things up so that if OSX Qt term > still doesn't function we might find the source of the problem. I wrote a clean patch which I placed here https://sourceforge.net/p/gnuplot/patches/653/ for cleaning up the linking and waiting for gnuplot_qt socket. This has no thread-related code. It is simply what I think is improved use of existing Qt class member functions for waiting. The basic summary is that the while loops which "poll" for input or response are removed. To me, polling means whenever a loop just circulates as fast as possible when waiting on something. So, while there are some while loops still left in the code after this patch, they are of the variety that has a proper Qt wait mechanism which handles all that detail for us. As far as Mac OSX, I think there is nothing within qt_term.cpp anymore that is specific to OSX. A larger summary of changes is below, but please give the patch a try and let me know how things work. After this post I will write a follow-up post about threading and the possibility of speeding up qt_term transfer. Dan * I changed the QProcess to be a conventional one rather than a disconnected one. That way there is still some access to the process so that the constructed server name can be retrieved from the process itself rather than having to duplicate the construction of the name in multiple places. We can then use the Qt waiting mechanisms and get rid of the custom while loop that waits for an external server to appear. * Note: In qt_flushOutBuffer() the flush() is necessary because there is no event loop. If there were an event loop, just socket.write() would be enough. * I commented out // Avoid dead-locking when no more data is available if (qt->socket.bytesToWrite() > 0) qt->socket.waitForBytesWritten(-1); because I don't think it is necessary. I left it there just in case it is needed on some systems. I doubt it, though. * I added qt->socket.disconnectFromServer(); to the end of qt_atexit(). That routine waits for all pending data to be sent before returning and complains if one attempts to wait on disconnect. So, an additional wait-on-disconnect doesn't seem necessary. * I altered the way that qt_term waits on gnuplot_qt when it wants font property info. (We are going to need to add a similar routine in order to get the true terminal size back from gnuplot_qt term in to fix the issue Ethan noted.) I make use of the proper timeout mechanism for Qt rather than introducing "micro sleep" and timeouts of 0 or -1. If one reviews that hunk of code they'll realize it is pretty conventional, i.e., keep reading bytes until enough are read to fill sizeof(gp_event_t). It turns out that one read typically get all of the bytes necessary. * Even after this change, I don't like the fact that qt_sendFont() discards events. It is usually carriage returns from holding the Enter key down and an event slips in before gnuplot_qt receives GEFontMetricRequest. However, I'm not sure what to do without some kind of queueing mechanism. * Similar to the waiting on font info, I changed this while loop: while (qt->socket.bytesAvailable() >= (int)sizeof(gp_event_t)) { } because, as with Yuriy Kaminskiy, that construct doesn't sit well with me. Beyond seeming like it could get stuck in certain situations (maybe not), I don't like that it is whirling away waiting for the number of bytes to be sufficient. We should be using the Qt mechanism to do any type of waiting rather than doing polling. * I changed that construct for Windows as well. It looks like almost an exact copy so I suspect it shouldn't break Windows Qt term. But if it breaks something, we'll have to do another rev. * The only thing I worry about (and I've left a note in the code) is that when waiting for responses from gnuplot_qt (such as font props) if there was a preceeding plot that has a huge amount of data. If the plot doesn't complete in the timeout, then there could be an error. The proper thing would be to dynamically adjust the wait time. But let's hold off on that scheme. I defined DEFAULT_TIMEOUT at the top of qt_term.cpp and we can lengthen that if need be. * There may be a chance that Windows persist works correctly now. I changed the qt_atexit() function slightly to use Qt routines // This Qt function waits until pending data to write is complete. qt->socket.disconnectFromServer(); Before that change it seemed like qt_atexit() might be wrapping things up too briskly, not giving enough time for proper interchange and disconnect. Perhaps Windows automatically deletes the gnuplot_qt process without proper disconnect, or more likely the persist command wasn't making its way to gnuplot_qt. |
From: Mojca M. <moj...@gm...> - 2014-03-03 00:41:12
|
On Sun, Mar 2, 2014 at 11:28 PM, Daniel J Sebald wrote: > > I wrote a clean patch which I placed here > > https://sourceforge.net/p/gnuplot/patches/653/ I first faced problems with "plugin" Making all in plugin /bin/sh: line 0: cd: plugin: No such file or directory but after manually patching the Makefile (there is a fair chance that my setup is semi-broken in that respect, so I don't blame the sources until I do a few more tests from a totally clean CVS checkout), here are the initial problems again: gnuplot> plot sin(x) qt_sendFont: Not receiving font properties qt_sendFont: "QLocalSocket: Socket operation timed out" gnuplot> qt_processTermEvent received a GE_fontprops event. This should not have happened The plot finally appears after 15 seconds, without any labels, wrong window size (that's also a problem in trunk/HEAD). Gnuplot then never properly recovered (I never got any text labels). The second gnuplot run works. These are exactly the symptoms that Ethan fixed recently. Mojca |
From: Daniel J S. <dan...@ie...> - 2014-03-03 00:54:59
|
On 03/02/2014 06:41 PM, Mojca Miklavec wrote: > On Sun, Mar 2, 2014 at 11:28 PM, Daniel J Sebald wrote: >> >> I wrote a clean patch which I placed here >> >> https://sourceforge.net/p/gnuplot/patches/653/ > > I first faced problems with "plugin" > > Making all in plugin > /bin/sh: line 0: cd: plugin: No such file or directory Not sure what that is, as I don't see any instance of "plugin" in the patch. I am, however, disabling plugins when I build so maybe that is finding its way into the patch file somehow. > here > are the initial problems again: > > gnuplot> plot sin(x) > qt_sendFont: Not receiving font properties > qt_sendFont: "QLocalSocket: Socket operation timed out" > gnuplot> qt_processTermEvent received a GE_fontprops event. This > should not have happened Probably the flush isn't complete before waiting on the GE_fontprops event. Could you please search for this line in the code #if 0 // 2014mar02 NOT SURE THIS IS NEEDED and change 0 to 1? Thanks, Dan |
From: sfeam <sf...@us...> - 2014-03-03 01:02:38
|
On Monday, 03 March 2014 01:41:06 AM Mojca Miklavec wrote: > On Sun, Mar 2, 2014 at 11:28 PM, Daniel J Sebald wrote: > > > > I wrote a clean patch which I placed here > > > > https://sourceforge.net/p/gnuplot/patches/653/ > > I first faced problems with "plugin" > > Making all in plugin > /bin/sh: line 0: cd: plugin: No such file or directory That's a totally separate problem. The new .../demo/plugin directory is not being handled properly by autoconf/automake. I don't know how to fix it, but the answer for now is to use ./configure --disable-plugins > but after manually patching the Makefile (there is a fair chance that > my setup is semi-broken in that respect, so I don't blame the sources > until I do a few more tests from a totally clean CVS checkout), here > are the initial problems again: > > gnuplot> plot sin(x) > qt_sendFont: Not receiving font properties > qt_sendFont: "QLocalSocket: Socket operation timed out" > gnuplot> qt_processTermEvent received a GE_fontprops event. This > should not have happened > > The plot finally appears after 15 seconds, without any labels, wrong > window size (that's also a problem in trunk/HEAD). Gnuplot then never > properly recovered (I never got any text labels). > > The second gnuplot run works. > > These are exactly the symptoms that Ethan fixed recently. Yeah. I put my comments on the patch tracker, but in short the patch removes exactly the fixes I put in to handle the slow OSX font response. So I don't think this patch is going in the right direction for event handling. The initial fork+and wait of the external process may be cleaner in Dan's patch than it was before. But I think we should leave the event handling the way it is now. Ethan |
From: Daniel J S. <dan...@ie...> - 2014-03-03 01:17:45
|
On 03/02/2014 07:02 PM, sfeam wrote: > On Monday, 03 March 2014 01:41:06 AM Mojca Miklavec wrote: >> On Sun, Mar 2, 2014 at 11:28 PM, Daniel J Sebald wrote: >>> >>> I wrote a clean patch which I placed here >>> >>> https://sourceforge.net/p/gnuplot/patches/653/ >> >> I first faced problems with "plugin" >> >> Making all in plugin >> /bin/sh: line 0: cd: plugin: No such file or directory > > That's a totally separate problem. > The new .../demo/plugin directory is not being handled properly > by autoconf/automake. I don't know how to fix it, but the answer > for now is to use > ./configure --disable-plugins > >> but after manually patching the Makefile (there is a fair chance that >> my setup is semi-broken in that respect, so I don't blame the sources >> until I do a few more tests from a totally clean CVS checkout), here >> are the initial problems again: >> >> gnuplot> plot sin(x) >> qt_sendFont: Not receiving font properties >> qt_sendFont: "QLocalSocket: Socket operation timed out" >> gnuplot> qt_processTermEvent received a GE_fontprops event. This >> should not have happened >> >> The plot finally appears after 15 seconds, without any labels, wrong >> window size (that's also a problem in trunk/HEAD). Gnuplot then never >> properly recovered (I never got any text labels). >> >> The second gnuplot run works. >> >> These are exactly the symptoms that Ethan fixed recently. > > Yeah. I put my comments on the patch tracker, but in short the patch > removes exactly the fixes I put in to handle the slow OSX font response. > So I don't think this patch is going in the right direction for event > handling. > > The initial fork+and wait of the external process may be cleaner in > Dan's patch than it was before. But I think we should leave the event > handling the way it is now. OK, it's easy enough to pull out the few hunks for fork/wait and create a separate patch. Dan |