From: Yuriy K. <yu...@gm...> - 2014-02-13 11:10:05
|
sfeam wrote: > On Wednesday, 12 February 2014 08:50:18 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. >> >> Local event loop might work, but that seems like a lot of overhead to >> communicate every time with a remote program with any sort of high >> bandwidth. Local event loops are what dialog boxes can and often use. >> Overhead isn't an issue there. > > I don't agree that an event loop is needed for this particular purpose. > We don't have a case of asynchronous processes sending each other > signals at random times. We just want some way for the daughter > process to signal back to the parent process "I'm ready now, you can > proceed". And we want some way for the parent to wait for this > signal without burning CPU cycles. One would think from its name that > QLocalSocket::waitForConnected() provides exactly this service, but > evidently it doesn't. At least in linux it should be possible to have the > parent call sigwait(), and the daughter call kill(parent_pid, SIGUSR1). > No need to involve Qt in this. Signals is *increadibly* fragile IPC mechanism. There are very hard restriction on what is permitted in signal handlers (that frequently violated, which result in very hard-to-catch and nasty bugs), you can easily end up with racy code, signals may lost, etc. And kill(parent_pid,SIGUSR1) is, obviously, racy and dangerous (parent process can die before children noticed, pid can be reused, and you can kill wrong process [and default handler for SIGUSR1 terminates process!]). |