The hidden problem with using QProcess/KProcess in kdelibs...

Dawit A adawit at
Sat Jan 22 19:25:07 GMT 2011


I have long been bothered by a problem with VLC freezing when you
attempt to open the file dialog (CTRL+O). I finally decided to
investigate the issue and what I discovered is something I think
should be discussed here. The bug in VLC,, happens because a lot of
small issues combine to create an unfortunate problem. The main
problem is the fact that VLC does the following in its main function:

    signal (SIGPIPE, SIG_IGN);

    signal (SIGCHLD, SIG_DFL);

    sigset_t set;
    sigemptyset (&set);
   /* Synchronously intercepted POSIX signals.
     * In a threaded program such as VLC, the only sane way to handle signals
     * is to block them in all threads but one - this is the only way to
     * predict which thread will receive them. If any piece of code depends
     * on delivery of one of this signal it is intrinsically not thread-safe
     * and MUST NOT be used in VLC, whether we like it or not.
     * There is only one exception: if the signal is raised with
     * pthread_kill() - we do not use this in LibVLC but some pthread
     * implementations use them internally. You should really use conditions
     * for thread synchronization anyway.
     * Signal that request a clean shutdown, and force an unclean shutdown
     * if they are triggered again 2+ seconds later.
     * We have to handle SIGTERM cleanly because of daemon mode. */
    sigaddset (&set, SIGINT);
    sigaddset (&set, SIGHUP);
    sigaddset (&set, SIGQUIT);
    sigaddset (&set, SIGTERM);
    sigaddset (&set, SIGPIPE);
    sigaddset (&set, SIGCHLD);

    /* Block all these signals */
    pthread_sigmask (SIG_BLOCK, &set, NULL);

Why is that a problem ? Simply because when the open file dialog is
invoked in a KDE enviroment, the hook that opens the KDE file dialog
box gets invoked and it in turn calls the appropriate KFileDialog::*
counter parts to QFileDaialog. If you then follow what happens in the
backtrace I posted when it freezes,, you will see that a
function called KMimeTypeRepository::sharedMimeInfoVersion gets
invoked soon before the freeze.

What happens in this function ? Well a QProcess is used to determine
the version number of the update-mime-database command and QProcess
relies on the SIG_CHLD signals which the app has blocked above! That
means any call to QProcess::waitForFinished() would block forever
unless a timeout value is specified ; which it is by default for 30
secs. Since KMimeTypeRepository::sharedMimeInfoVersion calls
waitForFinished with its default timeout, you get a 30 secs freeze.
But that is not all... Because QProcess returned without actually
finishing the job, when the QProcess dtor is invoked, it too waits for
the process to finish, which means another 30 secs for the default
case. As a result you get about 1 min freeze the first time you open
the file dialog box in VLC under KDE. Fortunately KMimeTypeRepository
caches the version number information so the freeze only happen
happens the first time the open dialog is invoked.

Anyhow, this problem is not specific to VLC and can happen to any Qt
application that blocks the SIGCHLD signals from reaching any of the
threads. As such I think some action needs to be taken to address this
issue. We can workaround this issue by unseting and setting the signal
masks in the aforementioned function, but there are many other places
in kdelibs where QProcess is used so perhaps a better resolution is
needed for this ? Perhaps it is QProcess that should be taking care of
this itself ?

Dawit A.

More information about the kde-core-devel mailing list