]> git.sesse.net Git - vlc/blobdiff - src/misc/threads.c
Fix compilation warning.
[vlc] / src / misc / threads.c
index 0ae8fb4a1d236f9b84ce5262a8cbb0700085c9a5..bd23b3a0ab038a4f21910ec144c180d2fc287b95 100644 (file)
@@ -101,14 +101,13 @@ void vlc_pthread_fatal (const char *action, int error,
 {
     fprintf (stderr, "LibVLC fatal error %s in thread %lu at %s:%u: %d\n",
              action, vlc_threadid (), file, line, error);
-    fflush (stderr);
 
     /* Sometimes strerror_r() crashes too, so make sure we print an error
      * message before we invoke it */
 #ifdef __GLIBC__
     /* Avoid the strerror_r() prototype brain damage in glibc */
     errno = error;
-    dprintf (2, " Error message: %m at:\n");
+    fprintf (stderr, " Error message: %m at:\n");
 #else
     char buf[1000];
     const char *msg;
@@ -126,8 +125,8 @@ void vlc_pthread_fatal (const char *action, int error,
             break;
     }
     fprintf (stderr, " Error message: %s\n", msg);
-    fflush (stderr);
 #endif
+    fflush (stderr);
 
 #ifdef HAVE_BACKTRACE
     void *stack[20];
@@ -467,6 +466,12 @@ static THREAD_RTYPE thread_entry (void *data)
     msg_Dbg (obj, "thread started");
     func (obj);
     msg_Dbg (obj, "thread ended");
+
+    libvlc_priv_t *libpriv = libvlc_priv (obj->p_libvlc);
+    vlc_mutex_lock (&libpriv->threads_lock);
+    if (--libpriv->threads_count == 0)
+        vlc_cond_signal (&libpriv->threads_wait);
+    vlc_mutex_unlock (&libpriv->threads_lock);
     return THREAD_RVAL;
 }
 
@@ -482,6 +487,7 @@ int __vlc_thread_create( vlc_object_t *p_this, const char * psz_file, int i_line
 {
     int i_ret;
     vlc_object_internals_t *p_priv = vlc_internals( p_this );
+    libvlc_priv_t *libpriv = libvlc_priv (p_this->p_libvlc);
 
     struct vlc_thread_boot *boot = malloc (sizeof (*boot));
     if (boot == NULL)
@@ -489,26 +495,34 @@ int __vlc_thread_create( vlc_object_t *p_this, const char * psz_file, int i_line
     boot->entry = func;
     boot->object = p_this;
 
-    vlc_mutex_lock( &p_this->object_lock );
+    vlc_mutex_lock (&libpriv->threads_lock);
+    libpriv->threads_count++;
+    vlc_mutex_unlock (&libpriv->threads_lock);
+
+    vlc_object_lock( p_this );
 
 #if defined( LIBVLC_USE_PTHREAD )
     pthread_attr_t attr;
     pthread_attr_init (&attr);
 
+    /* Block the signals that signals interface plugin handles.
+     * If the LibVLC caller wants to handle some signals by itself, it should
+     * block these before whenever invoking LibVLC. And it must obviously not
+     * start the VLC signals interface plugin.
+     *
+     * LibVLC will normally ignore any interruption caused by an asynchronous
+     * signal during a system call. But there may well be some buggy cases
+     * where it fails to handle EINTR (bug reports welcome). Some underlying
+     * libraries might also not handle EINTR properly.
+     */
     sigset_t set, oldset;
-    /* We really don't want signals to (literaly) interrupt our blocking I/O
-     * system calls. SIGPIPE is especially bad, as it can be caused by remote
-     * peers through connected sockets. Generally, we cannot know which signals
-     * are handled by the main program. Also, external LibVLC bindings tend not
-     * to setup a proper signal mask before invoking LibVLC.
-     * Hence, we hereby block all signals, except those for which blocking is
-     * undefined, as listed below. Note that SIGKILL and SIGSTOP need not be
-     * listed (see the documentation for pthread_sigmask) here. */
-    sigfillset (&set);
-    sigdelset (&set, SIGFPE);
-    sigdelset (&set, SIGILL);
-    sigdelset (&set, SIGSEGV);
-    sigdelset (&set, SIGBUS);
+    sigemptyset (&set);
+    sigdelset (&set, SIGHUP);
+    sigaddset (&set, SIGINT);
+    sigaddset (&set, SIGQUIT);
+    sigaddset (&set, SIGTERM);
+
+    sigaddset (&set, SIGPIPE); /* We don't want this one, really! */
     pthread_sigmask (SIG_BLOCK, &set, &oldset);
 
 #ifndef __APPLE__
@@ -591,7 +605,15 @@ int __vlc_thread_create( vlc_object_t *p_this, const char * psz_file, int i_line
                          psz_name, psz_file, i_line );
     }
 
-    vlc_mutex_unlock( &p_this->object_lock );
+    vlc_object_unlock( p_this );
+
+    if (i_ret)
+    {
+        vlc_mutex_lock (&libpriv->threads_lock);
+        if (--libpriv->threads_count == 0)
+            vlc_cond_signal (&libpriv->threads_wait);
+        vlc_mutex_unlock (&libpriv->threads_lock);
+    }
     return i_ret;
 }