|
From: Daniel J S. <dan...@ie...> - 2012-01-05 07:35:49
|
On 01/05/2012 12:58 AM, sfeam (Ethan Merritt) wrote: > On Wednesday, 04 January 2012, Daniel J Sebald wrote: >> On 01/04/2012 11:20 PM, sfeam (Ethan Merritt) wrote: >>> On Wednesday, 04 January 2012, Daniel J Sebald wrote: >> [snip] >>> Dan: >>> >>> I could be wrong, but I don't think that "application.exec()" is actually >>> an exec() call in the normal linux sense. See for example >>> http://stackoverflow.com/questions/3880693/qapplication-exec-creates-new-thread-process >>> >>> In this case it just means "start looping over the draw commands until I >>> tell you to stop". So your idea would be spot on if this were a real exec(), >>> but I'm afraid it's not going to help in this case. But hey, I could be wrong. >>> It's simple enough to give it a try. >> >> Oh, that's a problem then. The the code following the fork probably >> needs to be written as a separate program and run via exec(). That's >> considerable more work. >> >> Sorry, I can't find application.exec() > > It's inherited from the generic QtApplication.exec() > >> , but if all it does is reads >> commands until done, then after that exit(0), why does this process need >> to be forked? (Maybe you don't know the reason.) > > The parent process is the usual gnuplot core code. > The child process is the Qt display event loop, which manages the plot > window, traps mouse events, and so on. > The parent and child communicate via a shared channel that was set up > before the fork(). This stuff is all conveniently handled by the Qt > library routines, so you don't see much of it in the gnuplot code proper. > > Here's how I understand it. > Suppose the core code wants to draw a point at (x,y). > The call from the gnuplot side looks like this > (term->point)(x,y,type) > But the different terminals do very different things. > > Non-interactive terminals: > Call a library routine > (synchronous; part of the same process) > x11: > Send the command over a pipe to gnuplot_x11 > (asynchronous; totally separate process) > qt: > Send the command via a shared channel to the Qt event loop > (asynchronous; forked copy of the original process) > > I'm a bit fuzzy on how wxt works. I _think_ it works the same as qt > except that the fork is hidden inside the wxWidgets support code. > If you run gnuplot using the wxt terminal you can see that it starts > up a separate thread. For a very long time people had trouble with > wxt on OSX for I guess the same reason as we're now having trouble > with qt. However, somehow the wxt code was tweaked to avoid this > specific OSX error (I am very hazy on that part!) One might think > a similar tweak would work for Qt, but the web page that Mojca found > says that tripping over this OSX limitation in QtCore is "unavoidable". The statement at that reference is slightly vague on the matter: /** Calling CoreFoundation APIs (which is unavoidable in Qt/Mac) has always had issues on Mac OS X, but as of 10.5 is explicitly disallowed with an exception. As a result, in the case where we would normally fork and then dlopen code, or continue to run other code, we must now fork-and-exec. See "CoreFoundation and fork()" at http://developer.apple.com/releasenotes/CoreFoundation/CoreFoundation.html */ I think it means that Qt has to call some Apple-written APIs (Lion/Cocoa/Carbon/CoreServices). But the "we" here--does that mean the Qt developers writing the Qt code now have to use fork-and-exec? Or does that mean the people using the Qt utility have to use fork-and-exec? If it is the former, then perhaps Qt users should not be using fork, but QThread. Anyway, here is that missing discussion on CoreFoundation and fork(): http://osdir.com/ml/darwin-dev/2009-05/msg00020.html "CoreFoundation cannot be used on the child-side of fork()" Dan |