|
From: Daniel J S. <dan...@ie...> - 2012-01-05 11:18:20
|
On 01/05/2012 01:35 AM, Daniel J Sebald wrote: > 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. Eh, the QThread isn't exactly analogous to process. A QThread has its own stack, but memory is shared across threads. It's sort of like threads inside the QApplication. No use. I see a statement that QApplication needs to be the one and only event loop in a process to work correctly. Hence the need for a fork I would assume. (I'm guessing the exit(0) in qt_init() applies to the child process. Exiting gnuplot would make no sense.) Why Qt doesn't handle this, I don't know. Be that as it may, it might pay to step back a bit and consider just what the QApplication is doing. But first, let me ask whether // Start application.exec(); exit(0); should be _exit(0) instead of exit(0). A child shouldn't flush parent files: http://www.cs.uleth.ca/~holzmann/C/system/pipeforkexec.html The bigger question is whether this approach to creating a GUI QApplication, using fork() alone, is the best. It is sort of a hybrid of two worlds, the QApplication being another process ID while at the same time still being a object instance in the parent space. I suppose it works, but it's also somewhat of an odd feeling. Also, these lines of code: // Make sure the forked copy doesn't trash the history file cancel_history(); and // The creation of a QApplication mangled our locale settings #ifdef HAVE_LOCALE_H setlocale(LC_NUMERIC, "C"); setlocale(LC_TIME, current_locale); #endif are somewhat kluge-like in the sense they shouldn't be necessary. (I wonder if the mangled locale settings is because the child code used exit() instead of _exit().) Jérôme, do you think it would make sense to set up initialization of the Qt terminal similar to the gplt_x11 terminal for better organization and enable function under OS X at the same time? That is, put these lines into a small separate C executable: main(appropriate vectors) { signal(SIGINT, SIG_IGN); // Do not listen to SIGINT signals anymore #ifndef HAVE_QT_47 /* * FIXME: EAM Nov 2011 * It is better to use environmental variable * QT_GRAPHICSSYSTEM but this requires qt >= 4.7 * "raster" is ~5x faster than "native" (default). * Unfortunately "opengl" isn't recognized on my test systems :-( */ // This makes a huge difference to the speed of polygon rendering. // Alternatives are "native", "raster", "opengl" QApplication::setGraphicsSystem("raster"); #endif QtGnuplotApplication application(argc, (char**)( NULL)); // Make sure the forked copy doesn't trash the history file cancel_history(); // Load translations for the qt library QTranslator qtTranslator; qtTranslator.load("qt_" + QLocale::system().name(), QLibraryInfo::location(QLibraryInfo::TranslationsPath)); application.installTranslator(&qtTranslator); // Load translations for the qt terminal QTranslator translator; translator.load("qtgnuplot_" + QLocale::system().name(), QTGNUPLOT_DATA_DIR); application.installTranslator(&translator); // Start application.exec(); exit(0); } And in the qt_init() have something like the following (I left out details, but they are available in x11.trm file): if (pid < 0) fprintf(stderr, "Forking error\n"); else if (pid == 0) // Child: start the GUI { execvp(qtterm_full_command_path, optvec); _exit(0); } The advantage of using execvp is that it sort of wipes the slate clean for creating the QApplication. Please give us your thoughts. Dan |