[vlc-commits] Work around QProcess bug (KDE bug #260719)

Rémi Denis-Courmont git at videolan.org
Sun Jan 23 16:49:23 CET 2011


vlc | branch: master | Rémi Denis-Courmont <remi at remlab.net> | Sun Jan 23 16:51:12 2011 +0200| [5094db41a412524093f99a7e8179f4364663d3e5] | committer: Rémi Denis-Courmont

Work around QProcess bug (KDE bug #260719)

> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=5094db41a412524093f99a7e8179f4364663d3e5
---

 bin/vlc.c |   46 ++++++++++++++++++++++++++--------------------
 1 files changed, 26 insertions(+), 20 deletions(-)

diff --git a/bin/vlc.c b/bin/vlc.c
index 70eeed0..c24cda9 100644
--- a/bin/vlc.c
+++ b/bin/vlc.c
@@ -84,12 +84,11 @@ static void exit_timeout (int signum)
 int main( int i_argc, const char *ppsz_argv[] )
 {
     /* The so-called POSIX-compliant MacOS X reportedly processes SIGPIPE even
-     * if it is blocked in all thread. Also some libraries want SIGPIPE blocked
-     * as they have no clue about signal masks.
+     * if it is blocked in all thread.
      * Note: this is NOT an excuse for not protecting against SIGPIPE. If
      * LibVLC runs outside of VLC, we cannot rely on this code snippet. */
     signal (SIGPIPE, SIG_IGN);
-    /* Restore default for SIGCHLD in case parent ignores it. */
+    /* Restore SIGCHLD in case our parent process ignores it. */
     signal (SIGCHLD, SIG_DFL);
 
 #ifdef HAVE_SETENV
@@ -129,19 +128,17 @@ int main( int i_argc, const char *ppsz_argv[] )
     sigset_t set;
 
     sigemptyset (&set);
-    /* Synchronously intercepted POSIX signals.
+    /* VLC uses sigwait() to dequeue interesting signals.
+     * For this to work, those signals must be blocked in all threads,
+     * including the thread calling sigwait() (see the man page for details).
      *
-     * 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.
+     * There are two advantages to sigwait() over traditional signal handlers:
+     *  - delivery is synchronous: no need to worry about async-safety,
+     *  - EINTR is not generated: other threads need not handle that error.
+     * That being said, some LibVLC programs do not use sigwait(). Therefore
+     * EINTR must still be handled cleanly, notably from poll() calls.
      *
-     * Signal that request a clean shutdown, and force an unclean shutdown
+     * Signals 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);
@@ -149,14 +146,23 @@ int main( int i_argc, const char *ppsz_argv[] )
     sigaddset (&set, SIGQUIT);
     sigaddset (&set, SIGTERM);
 
-    /* Signals that cause a no-op:
-     * - SIGPIPE might happen with sockets and would crash VLC. It MUST be
-     *   blocked by any LibVLC-dependent application, not just VLC.
-     * - SIGCHLD comes after exec*() (such as httpd CGI support) and must
-     *   be dequeued to cleanup zombie processes.
+    /* SIGPIPE can happen and would crash the process. On modern systems,
+     * the MSG_NOSIGNAL flag protects socket write operations against SIGPIPE.
+     * But we still need to block SIGPIPE when:
+     *  - writing to pipes,
+     *  - using write() instead of send() for code not specific to sockets.
+     * LibVLC code assumes that SIGPIPE is blocked. Other LibVLC applications
+     * shall block it (or handle it somehow) too.
      */
     sigaddset (&set, SIGPIPE);
-    sigaddset (&set, SIGCHLD);
+
+    /* SIGCHLD must be dequeued to clean up zombie child processes.
+     * Furthermore the handler must not be set to SIG_IGN (see above). */
+    /* Unfortunately, the QProcess class from Qt4 has a bug. It installs a
+     * custom signal handlers and gets stuck if it is not called. So we cannot
+     * use sigwait() for SIGCHLD:
+     * http://bugs.kde.org/show_bug.cgi?id=260719 */
+    //sigaddset (&set, SIGCHLD);
 
 #ifdef HAVE_MAEMO
     sigaddset (&set, SIGRTMIN);



More information about the vlc-commits mailing list