* ./bootstrap : Fixed an issue with old shell versions
authorChristophe Massiot <massiot@videolan.org>
Thu, 29 Aug 2002 23:53:22 +0000 (23:53 +0000)
committerChristophe Massiot <massiot@videolan.org>
Thu, 29 Aug 2002 23:53:22 +0000 (23:53 +0000)
* ALL : Added a priority argument to vlc_thread_create(), so that audio
and input threads can run with a higher real-time priority, on systems
allowing you to use priorities.

29 files changed:
bootstrap
doc/developer/Makefile
doc/developer/audio_output.xml
doc/developer/manual.xml
include/input_iovec.h [deleted file]
include/vlc_common.h
include/vlc_symbols.h
include/vlc_threads.h
include/vlc_threads_funcs.h [new file with mode: 0644]
modules/access/dvdplay/access.c
modules/access/dvdread/input.c
modules/access/vcd/vcd.c
modules/audio_output/alsa.c
modules/audio_output/arts.c
modules/audio_output/esd.c
modules/audio_output/oss.c
modules/codec/mpeg_video/decoder.c
modules/gui/beos/AudioOutput.cpp
modules/gui/qnx/aout.c
modules/misc/gtk_main.c
modules/video_output/directx/aout.c
modules/video_output/directx/vout.c
src/input/input.c
src/input/input_dec.c
src/interface/interface.c
src/misc/beos_specific.cpp
src/misc/threads.c
src/playlist/playlist.c
src/video_output/video_output.c

index 3c991f2..0ac4fbc 100755 (executable)
--- a/bootstrap
+++ b/bootstrap
@@ -1,14 +1,15 @@
 #! /bin/sh
 
 ##  bootstrap.sh file for vlc, the VideoLAN Client
-##  $Id: bootstrap,v 1.12 2002/08/28 19:48:16 massiot Exp $
+##  $Id: bootstrap,v 1.13 2002/08/29 23:53:22 massiot Exp $
 ##
 ##  Authors: Samuel Hocevar <sam@zoy.org>
 
 ###
 ###  get a sane environment
 ###
-export LANG=C
+LANG=C
+export LANG
 
 ###
 ###  argument check
index 27be11e..25f537e 100644 (file)
@@ -12,15 +12,18 @@ MAX_TEX_RECURSION=4
 #HTML_SS=/usr/lib/sgml/stylesheets/nwalsh-modular/html/docbook.dsl
 #PRINT_SS=/usr/lib/sgml/stylesheets/nwalsh-modular/print/docbook.dsl
 
+#JADE=jade
+#TYPE=sgml
+
 # For Mac OS X :
-#XML_DECL=/usr/lib/sgml/declaration/xml.decl
+XML_DECL=/sw/share/sgml/dsssl/docbook-dsssl-nwalsh/dtds/decls/xml.dcl
 HTML_SS=/sw/share/sgml/dsssl/docbook-dsssl-nwalsh/html/docbook.dsl
 PRINT_SS=/sw/share/sgml/dsssl/docbook-dsssl-nwalsh/print/docbook.dsl
+JADE=openjade
+TYPE=sgml
 
 all: manual
 
-#JADE=jade
-JADE=openjade
 
 manual: manual.txt manual.ps manual.html
 
@@ -30,7 +33,7 @@ manual.tex: audio_output.xml debugging.xml decoders.xml gfdl.xml glossary.xml hi
 # No it's not a joke
 
 manual.html: audio_output.xml debugging.xml decoders.xml gfdl.xml glossary.xml history.xml input.xml interface.xml manual.xml overview.xml ports.xml video_output.xml
-       $(JADE) -t sgml -V %section-autolabel% -V nochunks \
+       $(JADE) -t $(TYPE) -V %section-autolabel% -V nochunks \
          -d $(HTML_SS) $(XML_DECL) manual.xml > $@
 
 manual.dvi: manual.tex modules.eps ps.eps stream.eps ts.eps
@@ -42,7 +45,7 @@ manual.ps: manual.dvi
        dvips -f $< > $@
 
 manual.txt: audio_output.xml debugging.xml decoders.xml gfdl.xml glossary.xml history.xml input.xml interface.xml manual.xml overview.xml ports.xml video_output.xml
-       $(JADE) -t sgml -V nochunks -d $(HTML_SS) $(XML_DECL) manual.xml > dump.html
+       $(JADE) -t $(TYPE) -V nochunks -d $(HTML_SS) $(XML_DECL) manual.xml > dump.html
        lynx -force_html -dump dump.html > $@
        -rm -f dump.html
 
index 6c8e1cf..b919b24 100644 (file)
@@ -1,5 +1,45 @@
 <chapter> <title> The audio output layer </title>
 
+  <sect1> <title> Audio output overview </title>
+
+    <para>
+This chapter documents the audio output layer known under the "audio output 3" codename. It has first been released with VLC version 0.5.0. Previous versions use an antic API, which is no longer documented nor supported. You definitely should write new code only for aout3 and later.
+    </para>
+
+    <para>
+The audio output's main purpose is to take sound samples from one or several decoders (called "input streams" in this chapter), to mix them and write them to an output device (called "output stream"). During this process, transformations may be needed or asked by the user, and they will be performed by audio filters.
+    </para>
+
+    <para>
+(insert here a schematic of the data flow in aout3)
+    </para>
+
+    <sect2> <title> Typical runcourse </title>
+
+      <para>
+The input spawns a new decoder audio decoder, say for instance an A/52 decoder. The A/52 decoder parses the sync info for format information, and creates a new aout "input stream" whith aout_InputNew().
+      </para>
+
+    </sect2>
+
+  </sect1>
+  
+  <sect1> <title> API for the decoders </title>
+  
+  </sect1>
+  
+  <sect1> <title> API for the output module </title>
+  
+  </sect1>
+  
+  <sect1> <title> Writing an audio filter </title>
+  
+  </sect1>
+  
+  <sect1> <title> Writing an audio mixer </title>
+  
+  </sect1>
+
   <sect1> <title> Data exchanges between a decoder and the audio output
   </title>
 
index d27a67b..0783051 100644 (file)
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="iso-8859-1"?>
 
-<!DOCTYPE book PUBLIC "-//Norman Walsh//DTD DocBk XML V3.1.3//EN" "docbookx.dtd"
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN" "/sw/share/xml/dtd/docbookx/4.1.2/docbookx.dtd"
 [
     <!ENTITY glossary SYSTEM "glossary.xml">
     <!ENTITY overview SYSTEM "overview.xml">
@@ -57,7 +57,7 @@
       <orgname> VideoLAN project </orgname>
     </affiliation>
   </collab>
-  <pubdate> $Id: manual.xml,v 1.2 2001/11/13 12:09:17 henri Exp $ </pubdate>
+  <pubdate> $Id: manual.xml,v 1.3 2002/08/29 23:53:22 massiot Exp $ </pubdate>
   <copyright> <year> 2001 </year>
               <holder> Christophe Massiot, for IDEALX S.A.S. </holder>
   </copyright>
diff --git a/include/input_iovec.h b/include/input_iovec.h
deleted file mode 100644 (file)
index b2cd4c2..0000000
+++ /dev/null
@@ -1,79 +0,0 @@
-/*****************************************************************************
- * input_iovec.h: iovec structure
- *****************************************************************************
- * Copyright (C) 2001 VideoLAN
- *
- * Authors: Samuel Hocevar <sam@zoy.org>
- *          Jon Lech Johansen <jon-vl@nanocrew.net>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- * 
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
- *****************************************************************************/
-
-/*****************************************************************************
- * iovec structure: vectored data entry
- *****************************************************************************/
-struct iovec
-{
-    void *iov_base;     /* Pointer to data. */
-    size_t iov_len;     /* Length of data.  */
-};
-
-/*****************************************************************************
- * readv_*: readv() replacements for iovec-impaired C libraries
- *****************************************************************************/
-#if defined( WIN32 )
-static inline int readv( int i_fd, struct iovec *p_iovec, int i_count )
-{
-    int i_index, i_len, i_total = 0;
-    unsigned char *p_base;
-    int i_bytes;
-
-    for( i_index = i_count; i_index; i_index-- )
-    {
-
-        i_len  = p_iovec->iov_len;
-        p_base = p_iovec->iov_base;
-
-        /* Loop is unrolled one time to spare the (i_bytes <= 0) test */
-
-        if( i_len > 0 )
-        {
-            i_bytes = read( i_fd, p_base, i_len );
-
-            if( i_bytes < 0 )
-            {
-                /* One of the reads failed, too bad.
-                   We won't even bother returning the reads that went ok,
-                   and as in the posix spec the file postition is left
-                   unspecified after a failure */
-                return -1;
-            }
-
-            i_total += i_bytes;
-
-            if( i_bytes != i_len )
-            {
-                /* we reached the end of the file or a signal interrupted
-                   the read */
-                return i_total;
-            }
-        }
-
-        p_iovec++;
-    }
-
-    return i_total;
-}
-#endif /* WIN32 */
index 537f84c..cae6d40 100644 (file)
@@ -3,7 +3,7 @@
  * Collection of useful common types and macros definitions
  *****************************************************************************
  * Copyright (C) 1998, 1999, 2000 VideoLAN
- * $Id: vlc_common.h,v 1.24 2002/08/26 23:36:20 sam Exp $
+ * $Id: vlc_common.h,v 1.25 2002/08/29 23:53:22 massiot Exp $
  *
  * Authors: Samuel Hocevar <sam@via.ecp.fr>
  *          Vincent Seguin <seguin@via.ecp.fr>
@@ -493,6 +493,7 @@ typedef __int64 off_t;
 #include "vlc_symbols.h"
 #include "os_specific.h"
 #include "vlc_messages.h"
+#include "vlc_threads_funcs.h"
 #include "mtime.h"
 #include "modules.h"
 #include "main.h"
index 570243f..05639dd 100644 (file)
@@ -34,7 +34,7 @@ struct module_symbols_t
     int (* __vlc_cond_init_inner) ( vlc_object_t *, vlc_cond_t * ) ;
     int (* __vlc_mutex_destroy_inner) ( char *, int, vlc_mutex_t * ) ;
     int (* __vlc_mutex_init_inner) ( vlc_object_t *, vlc_mutex_t * ) ;
-    int (* __vlc_thread_create_inner) ( vlc_object_t *, char *, int, char *, void * ( * ) ( void * ), vlc_bool_t ) ;
+    int (* __vlc_thread_create_inner) ( vlc_object_t *, char *, int, char *, void * ( * ) ( void * ), int, vlc_bool_t ) ;
     int (* __vlc_threads_end_inner) ( vlc_object_t * ) ;
     int (* __vlc_threads_init_inner) ( vlc_object_t * ) ;
     int (* input_AccessInit_inner) ( input_thread_t * ) ;
index 5836604..4cda186 100644 (file)
@@ -1,13 +1,14 @@
 /*****************************************************************************
- * threads.h : threads implementation for the VideoLAN client
- * This header provides a portable threads implementation.
+ * vlc_threads.h : threads implementation for the VideoLAN client
+ * This header provides portable declarations for mutexes & conditions
  *****************************************************************************
- * Copyright (C) 1999, 2000 VideoLAN
- * $Id: vlc_threads.h,v 1.9 2002/08/08 00:35:10 sam Exp $
+ * Copyright (C) 1999, 2002 VideoLAN
+ * $Id: vlc_threads.h,v 1.10 2002/08/29 23:53:22 massiot Exp $
  *
  * Authors: Jean-Marc Dressler <polux@via.ecp.fr>
  *          Samuel Hocevar <sam@via.ecp.fr>
  *          Gildas Bazin <gbazin@netcourrier.com>
+ *          Christophe Massiot <massiot@via.ecp.fr>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
 
 /*****************************************************************************
  * Constants
- *****************************************************************************
- * These constants are used by all threads in *_CreateThread() and
- * *_DestroyThreads() functions. Since those calls are non-blocking, an integer
- * value is used as a shared flag to represent the status of the thread.
  *****************************************************************************/
 
-/* Void status - this value can be used to make sure no operation is currently
- * in progress on the concerned thread in an array of recorded threads */
-#define THREAD_NOP          0                            /* nothing happened */
+/* Thread priorities */
+#ifdef SYS_DARWIN
+#   define VLC_THREAD_PRIORITY_LOW 10
+#   define VLC_THREAD_PRIORITY_INPUT 37
+#   define VLC_THREAD_PRIORITY_AUDIO 38
+#   define VLC_THREAD_PRIORITY_OUTPUT 38
 
-/* Creation status */
-#define THREAD_CREATE       10                     /* thread is initializing */
-#define THREAD_START        11                          /* thread has forked */
-#define THREAD_READY        19                            /* thread is ready */
+#elif defined(WIN32)
+#   define VLC_THREAD_PRIORITY_LOW 0
+#   define VLC_THREAD_PRIORITY_INPUT THREAD_PRIORITY_ABOVE_NORMAL
+#   define VLC_THREAD_PRIORITY_AUDIO THREAD_PRIORITY_ABOVE_NORMAL
+#   define VLC_THREAD_PRIORITY_OUTPUT THREAD_PRIORITY_ABOVE_NORMAL
 
-/* Destructions status */
-#define THREAD_DESTROY      20            /* destruction order has been sent */
-#define THREAD_END          21        /* destruction order has been received */
-#define THREAD_OVER         29             /* thread does not exist any more */
+#else
+#   define VLC_THREAD_PRIORITY_LOW 0
+#   define VLC_THREAD_PRIORITY_INPUT 0
+#   define VLC_THREAD_PRIORITY_AUDIO 0
+#   define VLC_THREAD_PRIORITY_OUTPUT 0
 
-/* Error status */
-#define THREAD_ERROR        30                           /* an error occured */
-#define THREAD_FATAL        31  /* an fatal error occured - program must end */
+#endif
 
 /*****************************************************************************
  * Type definitions
 
 #if defined( PTH_INIT_IN_PTH_H )
 typedef pth_t            vlc_thread_t;
-typedef pth_mutex_t      vlc_mutex_t;
-typedef pth_cond_t       vlc_cond_t;
+typedef struct
+{
+    pth_mutex_t mutex;
+    vlc_object_t * p_this;
+} vlc_mutex_t;
+typedef struct
+{
+    pth_cond_t cond;
+    vlc_object_t * p_this;
+} vlc_cond_t;
 
 #elif defined( ST_INIT_IN_ST_H )
 typedef st_thread_t *    vlc_thread_t;
-typedef st_mutex_t *     vlc_mutex_t;
-typedef st_cond_t *      vlc_cond_t;
+typedef struct
+{
+    st_mutex_t * mutex;
+    vlc_object_t * p_this;
+} vlc_mutex_t;
+typedef struct
+{
+    st_cond_t * cond;
+    vlc_object_t * p_this;
+} vlc_cond_t;
 
 #elif defined( WIN32 )
 typedef HANDLE vlc_thread_t;
@@ -112,6 +128,8 @@ typedef struct
     HANDLE              mutex;
     /* Win95/98/ME implementation */
     CRITICAL_SECTION    csection;
+
+    vlc_object_t * p_this;
 } vlc_mutex_t;
 
 typedef struct
@@ -124,15 +142,25 @@ typedef struct
     HANDLE              semaphore;
     CRITICAL_SECTION    csection;
     int                 i_win9x_cv;
+
+    vlc_object_t * p_this;
 } vlc_cond_t;
 
 #elif defined( PTHREAD_COND_T_IN_PTHREAD_H )
-typedef pthread_t        vlc_thread_t;
-typedef pthread_mutex_t  vlc_mutex_t;
-typedef pthread_cond_t   vlc_cond_t;
+typedef pthread_t       vlc_thread_t;
+typedef struct
+{
+    pthread_mutex_t mutex;
+    vlc_object_t * p_this;
+} vlc_mutex_t;
+typedef struct
+{
+    pthread_cond_t cond;
+    vlc_object_t * p_this;
+} vlc_cond_t;
 
 #elif defined( HAVE_CTHREADS_H )
-typedef cthread_t        vlc_thread_t;
+typedef cthread_t       vlc_thread_t;
 
 /* Those structs are the ones defined in /include/cthreads.h but we need
  * to handle (&foo) where foo is a (mutex_t) while they handle (foo) where
@@ -143,6 +171,8 @@ typedef struct
     spin_lock_t lock;
     char *name;
     struct cthread_queue queue;
+
+    vlc_object_t * p_this;
 } vlc_mutex_t;
 
 typedef struct
@@ -151,6 +181,8 @@ typedef struct
     struct cthread_queue queue;
     char *name;
     struct cond_imp *implications;
+
+    vlc_object_t * p_this;
 } vlc_cond_t;
 
 #elif defined( HAVE_KERNEL_SCHEDULER_H )
@@ -164,596 +196,17 @@ typedef struct
 {
     int32           init;
     sem_id          lock;
+
+    vlc_object_t * p_this;
 } vlc_mutex_t;
 
 typedef struct
 {
     int32           init;
     thread_id       thread;
-} vlc_cond_t;
-
-#endif
-
-/*****************************************************************************
- * Function definitions
- *****************************************************************************/
-VLC_EXPORT( int,  __vlc_threads_init,  ( vlc_object_t * ) );
-VLC_EXPORT( int,  __vlc_threads_end,   ( vlc_object_t * ) );
-VLC_EXPORT( int,  __vlc_mutex_init,    ( vlc_object_t *, vlc_mutex_t * ) );
-VLC_EXPORT( int,  __vlc_mutex_destroy, ( char *, int, vlc_mutex_t * ) );
-VLC_EXPORT( int,  __vlc_cond_init,     ( vlc_object_t *, vlc_cond_t * ) );
-VLC_EXPORT( int,  __vlc_cond_destroy,  ( char *, int, vlc_cond_t * ) );
-VLC_EXPORT( int,  __vlc_thread_create, ( vlc_object_t *, char *, int, char *, void * ( * ) ( void * ), vlc_bool_t ) );
-VLC_EXPORT( void, __vlc_thread_ready,  ( vlc_object_t * ) );
-VLC_EXPORT( void, __vlc_thread_join,   ( vlc_object_t *, char *, int ) );
-
-/*****************************************************************************
- * vlc_threads_init: initialize threads system
- *****************************************************************************/
-#define vlc_threads_init( P_THIS )                                          \
-    __vlc_threads_init( VLC_OBJECT(P_THIS) )
-
-/*****************************************************************************
- * vlc_threads_end: deinitialize threads system
- *****************************************************************************/
-#define vlc_threads_end( P_THIS )                                          \
-    __vlc_threads_end( VLC_OBJECT(P_THIS) )
-
-/*****************************************************************************
- * vlc_mutex_init: initialize a mutex
- *****************************************************************************/
-#define vlc_mutex_init( P_THIS, P_MUTEX )                                   \
-    __vlc_mutex_init( VLC_OBJECT(P_THIS), P_MUTEX )
-
-/*****************************************************************************
- * vlc_mutex_lock: lock a mutex
- *****************************************************************************/
-#ifdef DEBUG
-#   define vlc_mutex_lock( P_MUTEX )                                        \
-        __vlc_mutex_lock( __FILE__, __LINE__, P_MUTEX )
-#else
-#   define vlc_mutex_lock( P_MUTEX )                                        \
-        __vlc_mutex_lock( "(unknown)", 0, P_MUTEX )
-#endif
-
-static inline int __vlc_mutex_lock( char * psz_file, int i_line,
-                                    vlc_mutex_t *p_mutex )
-{
-#if defined( PTH_INIT_IN_PTH_H )
-    return pth_mutex_acquire( p_mutex, TRUE, NULL );
-
-#elif defined( ST_INIT_IN_ST_H )
-    return st_mutex_lock( *p_mutex );
-
-#elif defined( WIN32 )
-    if( p_mutex->mutex )
-    {
-        WaitForSingleObject( p_mutex->mutex, INFINITE );
-    }
-    else
-    {
-        EnterCriticalSection( &p_mutex->csection );
-    }
-    return 0;
-
-#elif defined( PTHREAD_COND_T_IN_PTHREAD_H )
-    int i_return = pthread_mutex_lock( p_mutex );
-    if( i_return )
-    {
-#if 0
-        msg_Err( "thread %d: mutex_lock failed at %s:%d (%s)",
-                 pthread_self(), psz_file, i_line, strerror(i_return) );
-#endif
-    }
-    return i_return;
-
-#elif defined( HAVE_CTHREADS_H )
-    mutex_lock( p_mutex );
-    return 0;
-
-#elif defined( HAVE_KERNEL_SCHEDULER_H )
-    status_t err;
-
-    if( !p_mutex )
-    {
-        return B_BAD_VALUE;
-    }
-
-    if( p_mutex->init < 2000 )
-    {
-        return B_NO_INIT;
-    }
-
-    err = acquire_sem( p_mutex->lock );
-    return err;
-
-#endif
-}
 
-/*****************************************************************************
- * vlc_mutex_unlock: unlock a mutex
- *****************************************************************************/
-#ifdef DEBUG
-#   define vlc_mutex_unlock( P_MUTEX )                                      \
-        __vlc_mutex_unlock( __FILE__, __LINE__, P_MUTEX )
-#else
-#   define vlc_mutex_unlock( P_MUTEX )                                      \
-        __vlc_mutex_unlock( "(unknown)", 0, P_MUTEX )
-#endif
-
-static inline int __vlc_mutex_unlock( char * psz_file, int i_line,
-                                      vlc_mutex_t *p_mutex )
-{
-#if defined( PTH_INIT_IN_PTH_H )
-    return pth_mutex_release( p_mutex );
-
-#elif defined( ST_INIT_IN_ST_H )
-    return st_mutex_unlock( *p_mutex );
-
-#elif defined( WIN32 )
-    if( p_mutex->mutex )
-    {
-        ReleaseMutex( p_mutex->mutex );
-    }
-    else
-    {
-        LeaveCriticalSection( &p_mutex->csection );
-    }
-    return 0;
-
-#elif defined( PTHREAD_COND_T_IN_PTHREAD_H )
-    int i_return = pthread_mutex_unlock( p_mutex );
-    if( i_return )
-    {
-#if 0
-        msg_Err( "thread %d: mutex_unlock failed at %s:%d (%s)",
-                 pthread_self(), psz_file, i_line, strerror(i_return) );
-#endif
-    }
-    return i_return;
-
-#elif defined( HAVE_CTHREADS_H )
-    mutex_unlock( p_mutex );
-    return 0;
-
-#elif defined( HAVE_KERNEL_SCHEDULER_H )
-    if( !p_mutex)
-    {
-        return B_BAD_VALUE;
-    }
-
-    if( p_mutex->init < 2000 )
-    {
-        return B_NO_INIT;
-    }
-
-    release_sem( p_mutex->lock );
-    return B_OK;
-
-#endif
-}
-
-/*****************************************************************************
- * vlc_mutex_destroy: destroy a mutex
- *****************************************************************************/
-#ifdef DEBUG
-#   define vlc_mutex_destroy( P_MUTEX )                                     \
-        __vlc_mutex_destroy( __FILE__, __LINE__, P_MUTEX )
-#else
-#   define vlc_mutex_destroy( P_MUTEX )                                     \
-        __vlc_mutex_destroy( "(unknown)", 0, P_MUTEX )
-#endif
-
-/*****************************************************************************
- * vlc_cond_init: initialize a condition
- *****************************************************************************/
-#define vlc_cond_init( P_THIS, P_COND )                                   \
-    __vlc_cond_init( VLC_OBJECT(P_THIS), P_COND )
-
-/*****************************************************************************
- * vlc_cond_signal: start a thread on condition completion
- *****************************************************************************/
-static inline int vlc_cond_signal( vlc_cond_t *p_condvar )
-{
-#if defined( PTH_INIT_IN_PTH_H )
-    return pth_cond_notify( p_condvar, FALSE );
-
-#elif defined( ST_INIT_IN_ST_H )
-    return st_cond_signal( *p_condvar );
-
-#elif defined( WIN32 )
-    /* Release one waiting thread if one is available. */
-    /* For this trick to work properly, the vlc_cond_signal must be surrounded
-     * by a mutex. This will prevent another thread from stealing the signal */
-    if( !p_condvar->semaphore )
-    {
-        PulseEvent( p_condvar->event );
-    }
-    else if( p_condvar->i_win9x_cv == 1 )
-    {
-        /* Wait for the gate to be open */
-        WaitForSingleObject( p_condvar->event, INFINITE );
-
-        if( p_condvar->i_waiting_threads )
-        {
-            /* Using a semaphore exposes us to a race condition. It is
-             * possible for another thread to start waiting on the semaphore
-             * just after we signaled it and thus steal the signal.
-             * We have to prevent new threads from entering the cond_wait(). */
-            ResetEvent( p_condvar->event );
-
-            /* A semaphore is used here because Win9x doesn't have
-             * SignalObjectAndWait() and thus a race condition exists
-             * during the time we release the mutex and the time we start
-             * waiting on the event (more precisely, the signal can sometimes
-             * be missed by the waiting thread if we use PulseEvent()). */
-            ReleaseSemaphore( p_condvar->semaphore, 1, 0 );
-        }
-    }
-    else
-    {
-        if( p_condvar->i_waiting_threads )
-        {
-            ReleaseSemaphore( p_condvar->semaphore, 1, 0 );
-
-            /* Wait for the last thread to be awakened */
-            WaitForSingleObject( p_condvar->event, INFINITE );
-        }
-    }
-    return 0;
-
-#elif defined( PTHREAD_COND_T_IN_PTHREAD_H )
-    return pthread_cond_signal( p_condvar );
-
-#elif defined( HAVE_CTHREADS_H )
-    /* condition_signal() */
-    if ( p_condvar->queue.head || p_condvar->implications )
-    {
-        cond_signal( (condition_t)p_condvar );
-    }
-    return 0;
-
-#elif defined( HAVE_KERNEL_SCHEDULER_H )
-    if( !p_condvar )
-    {
-        return B_BAD_VALUE;
-    }
-
-    if( p_condvar->init < 2000 )
-    {
-        return B_NO_INIT;
-    }
-
-    while( p_condvar->thread != -1 )
-    {
-        thread_info info;
-        if( get_thread_info(p_condvar->thread, &info) == B_BAD_VALUE )
-        {
-            return 0;
-        }
-
-        if( info.state != B_THREAD_SUSPENDED )
-        {
-            /* The  waiting thread is not suspended so it could
-             * have been interrupted beetwen the unlock and the
-             * suspend_thread line. That is why we sleep a little
-             * before retesting p_condver->thread. */
-            snooze( 10000 );
-        }
-        else
-        {
-            /* Ok, we have to wake up that thread */
-            resume_thread( p_condvar->thread );
-            return 0;
-        }
-    }
-    return 0;
-
-#endif
-}
-
-/*****************************************************************************
- * vlc_cond_broadcast: start all threads waiting on condition completion
- *****************************************************************************/
-/*
- * FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME
- * Only works with pthreads, you need to adapt it for others
- * FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME
- */
-static inline int vlc_cond_broadcast( vlc_cond_t *p_condvar )
-{
-#if defined( PTH_INIT_IN_PTH_H )
-    return pth_cond_notify( p_condvar, FALSE );
-
-#elif defined( ST_INIT_IN_ST_H )
-    return st_cond_broadcast( p_condvar );
-
-#elif defined( WIN32 )
-    /* Release all waiting threads. */
-    int i;
-
-    if( !p_condvar->semaphore )
-        for( i = p_condvar->i_waiting_threads; i > 0; i-- )
-            PulseEvent( p_condvar->event );
-    else if( p_condvar->i_win9x_cv == 1 )
-    {
-        /* Wait for the gate to be open */
-        WaitForSingleObject( p_condvar->event, INFINITE );
-
-        if( p_condvar->i_waiting_threads )
-        {
-            /* close gate */
-            ResetEvent( p_condvar->event );
-
-            ReleaseSemaphore( p_condvar->semaphore,
-                              p_condvar->i_waiting_threads, 0 );
-        }
-    }
-    else
-    {
-        if( p_condvar->i_waiting_threads )
-        {
-            ReleaseSemaphore( p_condvar->semaphore,
-                              p_condvar->i_waiting_threads, 0 );
-            /* Wait for the last thread to be awakened */
-            WaitForSingleObject( p_condvar->event, INFINITE );
-        }
-    }
-
-    return 0;
-
-#elif defined( PTHREAD_COND_T_IN_PTHREAD_H )
-    return pthread_cond_broadcast( p_condvar );
-
-#elif defined( HAVE_CTHREADS_H )
-    /* condition_signal() */
-    if ( p_condvar->queue.head || p_condvar->implications )
-    {
-        cond_signal( (condition_t)p_condvar );
-    }
-    return 0;
-
-#elif defined( HAVE_KERNEL_SCHEDULER_H )
-    if( !p_condvar )
-    {
-        return B_BAD_VALUE;
-    }
-
-    if( p_condvar->init < 2000 )
-    {
-        return B_NO_INIT;
-    }
-
-    while( p_condvar->thread != -1 )
-    {
-        thread_info info;
-        if( get_thread_info(p_condvar->thread, &info) == B_BAD_VALUE )
-        {
-            return 0;
-        }
-
-        if( info.state != B_THREAD_SUSPENDED )
-        {
-            /* The  waiting thread is not suspended so it could
-             * have been interrupted beetwen the unlock and the
-             * suspend_thread line. That is why we sleep a little
-             * before retesting p_condver->thread. */
-            snooze( 10000 );
-        }
-        else
-        {
-            /* Ok, we have to wake up that thread */
-            resume_thread( p_condvar->thread );
-            return 0;
-        }
-    }
-    return 0;
-
-#endif
-}
-
-/*****************************************************************************
- * vlc_cond_wait: wait until condition completion
- *****************************************************************************/
-#ifdef DEBUG
-#   define vlc_cond_wait( P_COND, P_MUTEX )                                   \
-        __vlc_cond_wait( __FILE__, __LINE__, P_COND, P_MUTEX  )
-#else
-#   define vlc_cond_wait( P_COND, P_MUTEX )                                   \
-        __vlc_cond_wait( "(unknown)", 0, P_COND, P_MUTEX )
-#endif
-
-static inline int __vlc_cond_wait( char * psz_file, int i_line,
-                                   vlc_cond_t *p_condvar, vlc_mutex_t *p_mutex )
-{
-#if defined( PTH_INIT_IN_PTH_H )
-    return pth_cond_await( p_condvar, p_mutex, NULL );
-
-#elif defined( ST_INIT_IN_ST_H )
-    int i_ret;
-
-    st_mutex_unlock( *p_mutex );
-    i_ret = st_cond_wait( *p_condvar );
-    st_mutex_lock( *p_mutex );
-
-    return i_ret;
-
-#elif defined( WIN32 )
-    if( !p_condvar->semaphore )
-    {
-        /* Increase our wait count */
-        p_condvar->i_waiting_threads++;
-
-        if( p_condvar->SignalObjectAndWait && p_mutex->mutex )
-        /* It is only possible to atomically release the mutex and initiate the
-         * waiting on WinNT/2K/XP. Win9x doesn't have SignalObjectAndWait(). */
-            p_condvar->SignalObjectAndWait( p_mutex->mutex,
-                                            p_condvar->event,
-                                            INFINITE, FALSE );
-        else
-        {
-            LeaveCriticalSection( &p_mutex->csection );
-            WaitForSingleObject( p_condvar->event, INFINITE );
-        }
-
-        p_condvar->i_waiting_threads--;
-    }
-    else if( p_condvar->i_win9x_cv == 1 )
-    {
-        int i_waiting_threads;
-
-        /* Wait for the gate to be open */
-        WaitForSingleObject( p_condvar->event, INFINITE );
-
-        /* Increase our wait count */
-        p_condvar->i_waiting_threads++;
-
-        LeaveCriticalSection( &p_mutex->csection );
-        WaitForSingleObject( p_condvar->semaphore, INFINITE );
-
-        /* Decrement and test must be atomic */
-        EnterCriticalSection( &p_condvar->csection );
-
-        /* Decrease our wait count */
-        i_waiting_threads = --p_condvar->i_waiting_threads;
-
-        LeaveCriticalSection( &p_condvar->csection );
-
-        /* Reopen the gate if we were the last waiting thread */
-        if( !i_waiting_threads )
-            SetEvent( p_condvar->event );
-    }
-    else
-    {
-        int i_waiting_threads;
-
-        /* Increase our wait count */
-        p_condvar->i_waiting_threads++;
-
-        LeaveCriticalSection( &p_mutex->csection );
-        WaitForSingleObject( p_condvar->semaphore, INFINITE );
-
-        /* Decrement and test must be atomic */
-        EnterCriticalSection( &p_condvar->csection );
-
-        /* Decrease our wait count */
-        i_waiting_threads = --p_condvar->i_waiting_threads;
-
-        LeaveCriticalSection( &p_condvar->csection );
-
-        /* Signal that the last waiting thread just went through */
-        if( !i_waiting_threads )
-            SetEvent( p_condvar->event );
-    }
-
-    /* Reacquire the mutex before returning. */
-    vlc_mutex_lock( p_mutex );
-
-    return 0;
-
-#elif defined( PTHREAD_COND_T_IN_PTHREAD_H )
-
-#   ifdef DEBUG
-    /* In debug mode, timeout */
-    struct timeval now;
-    struct timespec timeout;
-    int    i_result;
-
-    for( ; ; )
-    {
-        gettimeofday( &now, NULL );
-        timeout.tv_sec = now.tv_sec + THREAD_COND_TIMEOUT;
-        timeout.tv_nsec = now.tv_usec * 1000;
-
-        i_result = pthread_cond_timedwait( p_condvar, p_mutex, &timeout );
-
-        if( i_result == ETIMEDOUT )
-        {
-#if 0
-            msg_Warn( "thread %d: possible deadlock detected "
-                      "in cond_wait at %s:%d (%s)", pthread_self(),
-                      psz_file, i_line, strerror(i_result) );
-#endif
-            continue;
-        }
-
-        if( i_result )
-        {
-#if 0
-            msg_Err( "thread %d: cond_wait failed at %s:%d (%s)",
-                     pthread_self(), psz_file, i_line, strerror(i_result) );
-#endif
-        }
-        return( i_result );
-    }
-#   else
-    return pthread_cond_wait( p_condvar, p_mutex );
-#   endif
-
-#elif defined( HAVE_CTHREADS_H )
-    condition_wait( (condition_t)p_condvar, (mutex_t)p_mutex );
-    return 0;
-
-#elif defined( HAVE_KERNEL_SCHEDULER_H )
-    if( !p_condvar )
-    {
-        return B_BAD_VALUE;
-    }
-
-    if( !p_mutex )
-    {
-        return B_BAD_VALUE;
-    }
-
-    if( p_condvar->init < 2000 )
-    {
-        return B_NO_INIT;
-    }
-
-    /* The p_condvar->thread var is initialized before the unlock because
-     * it enables to identify when the thread is interrupted beetwen the
-     * unlock line and the suspend_thread line */
-    p_condvar->thread = find_thread( NULL );
-    vlc_mutex_unlock( p_mutex );
-    suspend_thread( p_condvar->thread );
-    p_condvar->thread = -1;
-
-    vlc_mutex_lock( p_mutex );
-    return 0;
+    vlc_object_t * p_this;
+} vlc_cond_t;
 
 #endif
-}
 
-/*****************************************************************************
- * vlc_cond_destroy: destroy a condition
- *****************************************************************************/
-#ifdef DEBUG
-#   define vlc_cond_destroy( P_COND )                                       \
-        __vlc_cond_destroy( __FILE__, __LINE__, P_COND )
-#else
-#   define vlc_cond_destroy( P_COND )                                       \
-        __vlc_cond_destroy( "(unknown)", 0, P_COND )
-#endif
-
-/*****************************************************************************
- * vlc_thread_create: create a thread
- *****************************************************************************/
-#   define vlc_thread_create( P_THIS, PSZ_NAME, FUNC, WAIT )                \
-        __vlc_thread_create( VLC_OBJECT(P_THIS), __FILE__, __LINE__, PSZ_NAME, (void * ( * ) ( void * ))FUNC, WAIT )
-
-/*****************************************************************************
- * vlc_thread_ready: tell the parent thread we were successfully spawned
- *****************************************************************************/
-#   define vlc_thread_ready( P_THIS )                                       \
-        __vlc_thread_ready( VLC_OBJECT(P_THIS) )
-
-/*****************************************************************************
- * vlc_thread_join: wait until a thread exits
- *****************************************************************************/
-#ifdef DEBUG
-#   define vlc_thread_join( P_THIS )                                        \
-        __vlc_thread_join( VLC_OBJECT(P_THIS), __FILE__, __LINE__ ) 
-#else
-#   define vlc_thread_join( P_THIS )                                        \
-        __vlc_thread_join( VLC_OBJECT(P_THIS), "(unknown)", 0 ) 
-#endif
diff --git a/include/vlc_threads_funcs.h b/include/vlc_threads_funcs.h
new file mode 100644 (file)
index 0000000..707a0b7
--- /dev/null
@@ -0,0 +1,660 @@
+/*****************************************************************************
+ * vlc_threads_funcs.h : threads implementation for the VideoLAN client
+ * This header provides a portable threads implementation.
+ *****************************************************************************
+ * Copyright (C) 1999, 2002 VideoLAN
+ * $Id: vlc_threads_funcs.h,v 1.1 2002/08/29 23:53:22 massiot Exp $
+ *
+ * Authors: Jean-Marc Dressler <polux@via.ecp.fr>
+ *          Samuel Hocevar <sam@via.ecp.fr>
+ *          Gildas Bazin <gbazin@netcourrier.com>
+ *          Christophe Massiot <massiot@via.ecp.fr>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
+ *****************************************************************************/
+
+/*****************************************************************************
+ * Function definitions
+ *****************************************************************************/
+VLC_EXPORT( int,  __vlc_threads_init,  ( vlc_object_t * ) );
+VLC_EXPORT( int,  __vlc_threads_end,   ( vlc_object_t * ) );
+VLC_EXPORT( int,  __vlc_mutex_init,    ( vlc_object_t *, vlc_mutex_t * ) );
+VLC_EXPORT( int,  __vlc_mutex_destroy, ( char *, int, vlc_mutex_t * ) );
+VLC_EXPORT( int,  __vlc_cond_init,     ( vlc_object_t *, vlc_cond_t * ) );
+VLC_EXPORT( int,  __vlc_cond_destroy,  ( char *, int, vlc_cond_t * ) );
+VLC_EXPORT( int,  __vlc_thread_create, ( vlc_object_t *, char *, int, char *, void * ( * ) ( void * ), int, vlc_bool_t ) );
+VLC_EXPORT( void, __vlc_thread_ready,  ( vlc_object_t * ) );
+VLC_EXPORT( void, __vlc_thread_join,   ( vlc_object_t *, char *, int ) );
+
+/*****************************************************************************
+ * vlc_threads_init: initialize threads system
+ *****************************************************************************/
+#define vlc_threads_init( P_THIS )                                          \
+    __vlc_threads_init( VLC_OBJECT(P_THIS) )
+
+/*****************************************************************************
+ * vlc_threads_end: deinitialize threads system
+ *****************************************************************************/
+#define vlc_threads_end( P_THIS )                                           \
+    __vlc_threads_end( VLC_OBJECT(P_THIS) )
+
+/*****************************************************************************
+ * vlc_mutex_init: initialize a mutex
+ *****************************************************************************/
+#define vlc_mutex_init( P_THIS, P_MUTEX )                                   \
+    __vlc_mutex_init( VLC_OBJECT(P_THIS), P_MUTEX )
+
+/*****************************************************************************
+ * vlc_mutex_lock: lock a mutex
+ *****************************************************************************/
+#define vlc_mutex_lock( P_MUTEX )                                           \
+    __vlc_mutex_lock( __FILE__, __LINE__, P_MUTEX )
+
+static inline int __vlc_mutex_lock( char * psz_file, int i_line,
+                                    vlc_mutex_t * p_mutex )
+{
+    int i_result;
+    /* In case of error : */
+    int i_thread = -1;
+    const char * psz_error = "";
+
+#if defined( PTH_INIT_IN_PTH_H )
+    i_result = pth_mutex_acquire( &p_mutex->mutex, TRUE, NULL );
+
+#elif defined( ST_INIT_IN_ST_H )
+    i_result = st_mutex_lock( *p_mutex->mutex );
+
+#elif defined( WIN32 )
+    if( p_mutex->mutex )
+    {
+        WaitForSingleObject( p_mutex->mutex, INFINITE );
+    }
+    else
+    {
+        EnterCriticalSection( &p_mutex->csection );
+    }
+    return 0;
+
+#elif defined( PTHREAD_COND_T_IN_PTHREAD_H )
+    i_result = pthread_mutex_lock( &p_mutex->mutex );
+    if ( i_result )
+    {
+        i_thread = (int)pthread_self();
+        psz_error = strerror(i_result);
+    }
+
+#elif defined( HAVE_CTHREADS_H )
+    mutex_lock( p_mutex->mutex );
+    return 0;
+
+#elif defined( HAVE_KERNEL_SCHEDULER_H )
+    if( p_mutex == NULL )
+    {
+        i_result = B_BAD_VALUE;
+    }
+    else if( p_mutex->init < 2000 )
+    {
+        i_result = B_NO_INIT;
+    }
+    else
+    {
+        i_result = acquire_sem( p_mutex->lock );
+    }
+#endif
+
+    if( i_result )
+    {
+        msg_Err( p_mutex->p_this,
+                 "thread %d: mutex_lock failed at %s:%d (%d:%s)",
+                 i_thread, psz_file, i_line, i_result, psz_error );
+    }
+    return i_result;
+}
+
+/*****************************************************************************
+ * vlc_mutex_unlock: unlock a mutex
+ *****************************************************************************/
+#define vlc_mutex_unlock( P_MUTEX )                                         \
+    __vlc_mutex_unlock( __FILE__, __LINE__, P_MUTEX )
+
+static inline int __vlc_mutex_unlock( char * psz_file, int i_line,
+                                      vlc_mutex_t *p_mutex )
+{
+    int i_result;
+    /* In case of error : */
+    int i_thread = -1;
+    const char * psz_error = "";
+
+#if defined( PTH_INIT_IN_PTH_H )
+    i_result = pth_mutex_release( &p_mutex->mutex );
+
+#elif defined( ST_INIT_IN_ST_H )
+    i_result = st_mutex_unlock( *p_mutex->mutex );
+
+#elif defined( WIN32 )
+    if( p_mutex->mutex )
+    {
+        ReleaseMutex( p_mutex->mutex );
+    }
+    else
+    {
+        LeaveCriticalSection( &p_mutex->csection );
+    }
+    return 0;
+
+#elif defined( PTHREAD_COND_T_IN_PTHREAD_H )
+    i_result = pthread_mutex_unlock( &p_mutex->mutex );
+    if ( i_result )
+    {
+        i_thread = (int)pthread_self();
+        psz_error = strerror(i_result);
+    }
+
+#elif defined( HAVE_CTHREADS_H )
+    mutex_unlock( p_mutex );
+    return 0;
+
+#elif defined( HAVE_KERNEL_SCHEDULER_H )
+    if( p_mutex == NULL )
+    {
+        i_result = B_BAD_VALUE;
+    }
+    else if( p_mutex->init < 2000 )
+    {
+        i_result = B_NO_INIT;
+    }
+    else
+    {
+        release_sem( p_mutex->lock );
+        return B_OK;
+    }
+#endif
+
+    if( i_result )
+    {
+        msg_Err( p_mutex->p_this,
+                 "thread %d: mutex_unlock failed at %s:%d (%d:%s)",
+                 i_thread, psz_file, i_line, i_result, psz_error );
+    }
+
+    return i_result;
+}
+
+/*****************************************************************************
+ * vlc_mutex_destroy: destroy a mutex
+ *****************************************************************************/
+#define vlc_mutex_destroy( P_MUTEX )                                        \
+    __vlc_mutex_destroy( __FILE__, __LINE__, P_MUTEX )
+
+/*****************************************************************************
+ * vlc_cond_init: initialize a condition
+ *****************************************************************************/
+#define vlc_cond_init( P_THIS, P_COND )                                     \
+    __vlc_cond_init( VLC_OBJECT(P_THIS), P_COND )
+
+/*****************************************************************************
+ * vlc_cond_signal: start a thread on condition completion
+ *****************************************************************************/
+#define vlc_cond_signal( P_COND )                                           \
+    __vlc_cond_signal( __FILE__, __LINE__, P_COND )
+
+static inline int __vlc_cond_signal( char * psz_file, int i_line,
+                                     vlc_cond_t *p_condvar )
+{
+    int i_result;
+    /* In case of error : */
+    int i_thread = -1;
+    const char * psz_error = "";
+
+#if defined( PTH_INIT_IN_PTH_H )
+    i_result = pth_cond_notify( &p_condvar->cond, FALSE );
+
+#elif defined( ST_INIT_IN_ST_H )
+    i_result = st_cond_signal( *p_condvar->cond );
+
+#elif defined( WIN32 )
+    /* Release one waiting thread if one is available. */
+    /* For this trick to work properly, the vlc_cond_signal must be surrounded
+     * by a mutex. This will prevent another thread from stealing the signal */
+    if( !p_condvar->semaphore )
+    {
+        PulseEvent( p_condvar->event );
+    }
+    else if( p_condvar->i_win9x_cv == 1 )
+    {
+        /* Wait for the gate to be open */
+        WaitForSingleObject( p_condvar->event, INFINITE );
+
+        if( p_condvar->i_waiting_threads )
+        {
+            /* Using a semaphore exposes us to a race condition. It is
+             * possible for another thread to start waiting on the semaphore
+             * just after we signaled it and thus steal the signal.
+             * We have to prevent new threads from entering the cond_wait(). */
+            ResetEvent( p_condvar->event );
+
+            /* A semaphore is used here because Win9x doesn't have
+             * SignalObjectAndWait() and thus a race condition exists
+             * during the time we release the mutex and the time we start
+             * waiting on the event (more precisely, the signal can sometimes
+             * be missed by the waiting thread if we use PulseEvent()). */
+            ReleaseSemaphore( p_condvar->semaphore, 1, 0 );
+        }
+    }
+    else
+    {
+        if( p_condvar->i_waiting_threads )
+        {
+            ReleaseSemaphore( p_condvar->semaphore, 1, 0 );
+
+            /* Wait for the last thread to be awakened */
+            WaitForSingleObject( p_condvar->event, INFINITE );
+        }
+    }
+    return 0;
+
+#elif defined( PTHREAD_COND_T_IN_PTHREAD_H )
+    i_result = pthread_cond_signal( &p_condvar->cond );
+    if ( i_result )
+    {
+        i_thread = (int)pthread_self();
+        psz_error = strerror(i_result);
+    }
+
+#elif defined( HAVE_CTHREADS_H )
+    /* condition_signal() */
+    if ( p_condvar->queue.head || p_condvar->implications )
+    {
+        cond_signal( (condition_t)p_condvar );
+    }
+    return 0;
+
+#elif defined( HAVE_KERNEL_SCHEDULER_H )
+    if( p_condvar == NULL )
+    {
+        i_result = B_BAD_VALUE;
+    }
+    else if( p_condvar->init < 2000 )
+    {
+        i_result = B_NO_INIT;
+    }
+    else
+    {
+        while( p_condvar->thread != -1 )
+        {
+            thread_info info;
+            if( get_thread_info(p_condvar->thread, &info) == B_BAD_VALUE )
+            {
+                return 0;
+            }
+
+            if( info.state != B_THREAD_SUSPENDED )
+            {
+                /* The  waiting thread is not suspended so it could
+                 * have been interrupted beetwen the unlock and the
+                 * suspend_thread line. That is why we sleep a little
+                 * before retesting p_condver->thread. */
+                snooze( 10000 );
+            }
+            else
+            {
+                /* Ok, we have to wake up that thread */
+                resume_thread( p_condvar->thread );
+                return 0;
+            }
+        }
+    }
+#endif
+
+    if( i_result )
+    {
+        msg_Err( p_condvar->p_this,
+                 "thread %d: cond_signal failed at %s:%d (%d:%s)",
+                 i_thread, psz_file, i_line, i_result, psz_error );
+    }
+
+    return i_result;
+}
+
+/*****************************************************************************
+ * vlc_cond_broadcast: start all threads waiting on condition completion
+ *****************************************************************************/
+/*
+ * FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME
+ * Only works with pthreads, st, win32
+ * You need to adapt it for others
+ * FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME
+ */
+#define vlc_cond_broadcast( P_COND )                                        \
+    __vlc_cond_broadcast( __FILE__, __LINE__, P_COND )
+
+static inline int __vlc_cond_broadcast( char * psz_file, int i_line,
+                                        vlc_cond_t *p_condvar )
+{
+    int i_result;
+    /* In case of error : */
+    int i_thread = -1;
+    const char * psz_error = "";
+
+#if defined( PTH_INIT_IN_PTH_H )
+    i_result = pth_cond_notify( &p_condvar->cond, FALSE );
+
+#elif defined( ST_INIT_IN_ST_H )
+    i_result = st_cond_broadcast( *p_condvar->cond );
+
+#elif defined( WIN32 )
+    /* Release all waiting threads. */
+    if( !p_condvar->semaphore )
+    {
+        for( i = p_condvar->i_waiting_threads; i > 0; i-- )
+        {
+            PulseEvent( p_condvar->event );
+        }
+    }
+    else if( p_condvar->i_win9x_cv == 1 )
+    {
+        /* Wait for the gate to be open */
+        WaitForSingleObject( p_condvar->event, INFINITE );
+
+        if( p_condvar->i_waiting_threads )
+        {
+            /* Using a semaphore exposes us to a race condition. It is
+             * possible for another thread to start waiting on the semaphore
+             * just after we signaled it and thus steal the signal.
+             * We have to prevent new threads from entering the cond_wait(). */
+            ResetEvent( p_condvar->event );
+
+            /* A semaphore is used here because Win9x doesn't have
+             * SignalObjectAndWait() and thus a race condition exists
+             * during the time we release the mutex and the time we start
+             * waiting on the event (more precisely, the signal can sometimes
+             * be missed by the waiting thread if we use PulseEvent()). */
+            ReleaseSemaphore( p_condvar->semaphore,
+                              p_condvar->i_waiting_threads, 0 );
+        }
+    }
+    else
+    {
+        if( p_condvar->i_waiting_threads )
+        {
+            ReleaseSemaphore( p_condvar->semaphore,
+                              p_condvar->i_waiting_threads, 0 );
+
+            /* Wait for the last thread to be awakened */
+            WaitForSingleObject( p_condvar->event, INFINITE );
+        }
+    }
+    return 0;
+
+#elif defined( PTHREAD_COND_T_IN_PTHREAD_H )
+    i_result = pthread_cond_broadcast( &p_condvar->cond );
+    if ( i_result )
+    {
+        i_thread = (int)pthread_self();
+        psz_error = strerror(i_result);
+    }
+
+#elif defined( HAVE_CTHREADS_H )
+    /* condition_signal() */
+    if ( p_condvar->queue.head || p_condvar->implications )
+    {
+        cond_signal( (condition_t)p_condvar );
+    }
+    return 0;
+
+#elif defined( HAVE_KERNEL_SCHEDULER_H )
+    if( p_condvar == NULL )
+    {
+        i_result = B_BAD_VALUE;
+    }
+    else if( p_condvar->init < 2000 )
+    {
+        i_result = B_NO_INIT;
+    }
+    else
+    {
+        while( p_condvar->thread != -1 )
+        {
+            thread_info info;
+            if( get_thread_info(p_condvar->thread, &info) == B_BAD_VALUE )
+            {
+                return 0;
+            }
+
+            if( info.state != B_THREAD_SUSPENDED )
+            {
+                /* The  waiting thread is not suspended so it could
+                 * have been interrupted beetwen the unlock and the
+                 * suspend_thread line. That is why we sleep a little
+                 * before retesting p_condver->thread. */
+                snooze( 10000 );
+            }
+            else
+            {
+                /* Ok, we have to wake up that thread */
+                resume_thread( p_condvar->thread );
+                return 0;
+            }
+        }
+    }
+#endif
+
+    if( i_result )
+    {
+        msg_Err( p_condvar->p_this,
+                 "thread %d: cond_broadcast failed at %s:%d (%d:%s)",
+                 i_thread, psz_file, i_line, i_result, psz_error );
+    }
+
+    return i_result;
+}
+
+/*****************************************************************************
+ * vlc_cond_wait: wait until condition completion
+ *****************************************************************************/
+#define vlc_cond_wait( P_COND, P_MUTEX )                                     \
+    __vlc_cond_wait( __FILE__, __LINE__, P_COND, P_MUTEX  )
+
+static inline int __vlc_cond_wait( char * psz_file, int i_line,
+                                   vlc_cond_t *p_condvar, vlc_mutex_t *p_mutex )
+{
+    int i_result;
+    /* In case of error : */
+    int i_thread = -1;
+    const char * psz_error = "";
+
+#if defined( PTH_INIT_IN_PTH_H )
+    i_result = pth_cond_await( &p_condvar->cond, &p_mutex->mutex, NULL );
+
+#elif defined( ST_INIT_IN_ST_H )
+    st_mutex_unlock( *p_mutex->mutex );
+    i_result = st_cond_wait( *p_condvar->cond );
+    st_mutex_lock( *p_mutex->mutex );
+
+#elif defined( WIN32 )
+    if( !p_condvar->semaphore )
+    {
+        /* Increase our wait count */
+        p_condvar->i_waiting_threads++;
+
+        if( p_condvar->SignalObjectAndWait && p_mutex->mutex )
+        {
+            /* It is only possible to atomically release the mutex and
+             * initiate the waiting on WinNT/2K/XP. Win9x doesn't have
+             * SignalObjectAndWait(). */
+            p_condvar->SignalObjectAndWait( p_mutex->mutex,
+                                            p_condvar->event,
+                                            INFINITE, FALSE );
+        }
+        else
+        {
+            LeaveCriticalSection( &p_mutex->csection );
+            WaitForSingleObject( p_condvar->event, INFINITE );
+        }
+
+        p_condvar->i_waiting_threads--;
+    }
+    else if( p_condvar->i_win9x_cv == 1 )
+    {
+        int i_waiting_threads;
+
+        /* Wait for the gate to be open */
+        WaitForSingleObject( p_condvar->event, INFINITE );
+
+        /* Increase our wait count */
+        p_condvar->i_waiting_threads++;
+
+        LeaveCriticalSection( &p_mutex->csection );
+        WaitForSingleObject( p_condvar->semaphore, INFINITE );
+
+        /* Decrement and test must be atomic */
+        EnterCriticalSection( &p_condvar->csection );
+
+        /* Decrease our wait count */
+        i_waiting_threads = --p_condvar->i_waiting_threads;
+
+        LeaveCriticalSection( &p_condvar->csection );
+
+        /* Reopen the gate if we were the last waiting thread */
+        if( !i_waiting_threads )
+            SetEvent( p_condvar->event );
+    }
+    else
+    {
+        int i_waiting_threads;
+
+        /* Increase our wait count */
+        p_condvar->i_waiting_threads++;
+
+        LeaveCriticalSection( &p_mutex->csection );
+        WaitForSingleObject( p_condvar->semaphore, INFINITE );
+
+        /* Decrement and test must be atomic */
+        EnterCriticalSection( &p_condvar->csection );
+
+        /* Decrease our wait count */
+        i_waiting_threads = --p_condvar->i_waiting_threads;
+
+        LeaveCriticalSection( &p_condvar->csection );
+
+        /* Signal that the last waiting thread just went through */
+        if( !i_waiting_threads )
+            SetEvent( p_condvar->event );
+    }
+
+    /* Reacquire the mutex before returning. */
+    vlc_mutex_lock( p_mutex );
+
+    return 0;
+
+#elif defined( PTHREAD_COND_T_IN_PTHREAD_H )
+
+#   ifdef DEBUG
+    /* In debug mode, timeout */
+    struct timeval now;
+    struct timespec timeout;
+
+    for( ; ; )
+    {
+        gettimeofday( &now, NULL );
+        timeout.tv_sec = now.tv_sec + THREAD_COND_TIMEOUT;
+        timeout.tv_nsec = now.tv_usec * 1000;
+
+        i_result = pthread_cond_timedwait( &p_condvar->cond, &p_mutex->mutex,
+                                           &timeout );
+
+        if( i_result == ETIMEDOUT )
+        {
+            msg_Warn( p_condvar->p_this,
+                      "thread %d: possible deadlock detected "
+                      "in cond_wait at %s:%d (%s)", pthread_self(),
+                      psz_file, i_line, strerror(i_result) );
+        }
+        else break;
+    }
+#   else
+    i_result = pthread_cond_wait( &p_condvar->cond, &p_mutex->mutex );
+#   endif
+
+    if ( i_result )
+    {
+        i_thread = (int)pthread_self();
+        psz_error = strerror(i_result);
+    }
+
+#elif defined( HAVE_CTHREADS_H )
+    condition_wait( (condition_t)p_condvar, (mutex_t)p_mutex );
+    return 0;
+
+#elif defined( HAVE_KERNEL_SCHEDULER_H )
+    if( p_condvar == NULL )
+    {
+        i_result = B_BAD_VALUE;
+    }
+    else if( p_mutex == NULL )
+    {
+        i_result = B_BAD_VALUE;
+    }
+    else if( p_condvar->init < 2000 )
+    {
+        i_result = B_NO_INIT;
+    }
+
+    /* The p_condvar->thread var is initialized before the unlock because
+     * it enables to identify when the thread is interrupted beetwen the
+     * unlock line and the suspend_thread line */
+    p_condvar->thread = find_thread( NULL );
+    vlc_mutex_unlock( p_mutex );
+    suspend_thread( p_condvar->thread );
+    p_condvar->thread = -1;
+
+    vlc_mutex_lock( p_mutex );
+    return 0;
+
+#endif
+
+    if( i_result )
+    {
+        msg_Err( p_condvar->p_this,
+                 "thread %d: cond_wait failed at %s:%d (%d:%s)",
+                 i_thread, psz_file, i_line, i_result, psz_error );
+    }
+
+    return i_result;
+}
+
+/*****************************************************************************
+ * vlc_cond_destroy: destroy a condition
+ *****************************************************************************/
+#define vlc_cond_destroy( P_COND )                                          \
+    __vlc_cond_destroy( __FILE__, __LINE__, P_COND )
+
+/*****************************************************************************
+ * vlc_thread_create: create a thread
+ *****************************************************************************/
+#define vlc_thread_create( P_THIS, PSZ_NAME, FUNC, PRIORITY, WAIT )         \
+    __vlc_thread_create( VLC_OBJECT(P_THIS), __FILE__, __LINE__, PSZ_NAME, (void * ( * ) ( void * ))FUNC, PRIORITY, WAIT )
+
+/*****************************************************************************
+ * vlc_thread_ready: tell the parent thread we were successfully spawned
+ *****************************************************************************/
+#define vlc_thread_ready( P_THIS )                                          \
+    __vlc_thread_ready( VLC_OBJECT(P_THIS) )
+
+/*****************************************************************************
+ * vlc_thread_join: wait until a thread exits
+ *****************************************************************************/
+#define vlc_thread_join( P_THIS )                                           \
+    __vlc_thread_join( VLC_OBJECT(P_THIS), __FILE__, __LINE__ ) 
index 9dcaf75..abbd83e 100644 (file)
@@ -2,7 +2,7 @@
  * access.c: access capabilities for dvdplay plugin.
  *****************************************************************************
  * Copyright (C) 2001 VideoLAN
- * $Id: access.c,v 1.2 2002/08/07 00:29:36 sam Exp $
+ * $Id: access.c,v 1.3 2002/08/29 23:53:22 massiot Exp $
  *
  * Author: St├ęphane Borel <stef@via.ecp.fr>
  *
 
 #if defined( WIN32 )
 #   include <io.h>                                                 /* read() */
-#else
-#   include <sys/uio.h>                                      /* struct iovec */
-#endif
-
-#if defined( WIN32 )
-#   include "input_iovec.h"
 #endif
 
 #include "dvd.h"
index 3324ea8..bcec9e6 100644 (file)
@@ -6,7 +6,7 @@
  * It depends on: libdvdread for ifo files and block reading.
  *****************************************************************************
  * Copyright (C) 2001 VideoLAN
- * $Id: input.c,v 1.2 2002/08/07 00:29:36 sam Exp $
+ * $Id: input.c,v 1.3 2002/08/29 23:53:22 massiot Exp $
  *
  * Author: St├ęphane Borel <stef@via.ecp.fr>
  *
 
 #if defined( WIN32 )
 #   include <io.h>                                                 /* read() */
-#else
-#   include <sys/uio.h>                                      /* struct iovec */
-#endif
-
-#if defined( WIN32 )
-#   include "input_iovec.h"
 #endif
 
 #include <dvdread/dvd_reader.h>
index b74d3d5..07956c8 100644 (file)
@@ -2,7 +2,7 @@
  * vcd.c : VCD input module for vlc
  *****************************************************************************
  * Copyright (C) 2000 VideoLAN
- * $Id: vcd.c,v 1.4 2002/08/08 22:28:22 sam Exp $
+ * $Id: vcd.c,v 1.5 2002/08/29 23:53:22 massiot Exp $
  *
  * Author: Johan Bilien <jobi@via.ecp.fr>
  *
 
 #if defined( WIN32 )
 #   include <io.h>                                                 /* read() */
-#else
-#   include <sys/uio.h>                                      /* struct iovec */
-#endif
-
-#if defined( WIN32 )
-#   include "input_iovec.h"
 #endif
 
 #include "vcd.h"
index 7e5ca61..26a589f 100644 (file)
@@ -2,7 +2,7 @@
  * alsa.c : alsa plugin for vlc
  *****************************************************************************
  * Copyright (C) 2000-2001 VideoLAN
- * $Id: alsa.c,v 1.8 2002/08/25 09:39:59 sam Exp $
+ * $Id: alsa.c,v 1.9 2002/08/29 23:53:22 massiot Exp $
  *
  * Authors: Henri Fallon <henri@videolan.org> - Original Author
  *          Jeffrey Baker <jwbaker@acm.org> - Port to ALSA 1.0 API
@@ -115,7 +115,8 @@ static int Open( vlc_object_t *p_this )
 
     /* Create ALSA thread and wait for its readiness. */
     p_sys->b_initialized = VLC_FALSE;
-    if( vlc_thread_create( p_aout, "aout", ALSAThread, VLC_FALSE ) )
+    if( vlc_thread_create( p_aout, "aout", ALSAThread,
+                           VLC_THREAD_PRIORITY_OUTPUT, VLC_FALSE ) )
     {
         msg_Err( p_aout, "cannot create ALSA thread (%s)", strerror(errno) );
         free( p_sys );
index 5508b1f..2785610 100644 (file)
@@ -101,7 +101,8 @@ static int Open( vlc_object_t *p_this )
 
     /* Create aRts thread and wait for its readiness. */
     p_sys->b_initialized = VLC_FALSE;
-    if( vlc_thread_create( p_aout, "aout", aRtsThread, VLC_FALSE ) )
+    if( vlc_thread_create( p_aout, "aout", aRtsThread,
+                           VLC_THREAD_PRIORITY_OUTPUT, VLC_FALSE ) )
     {
         msg_Err( p_aout, "cannot create aRts thread (%s)", strerror(errno) );
         free( p_sys );
index 38a3d4a..319acf6 100644 (file)
@@ -2,7 +2,7 @@
  * esd.c : EsounD module
  *****************************************************************************
  * Copyright (C) 2000, 2001 VideoLAN
- * $Id: esd.c,v 1.10 2002/08/25 09:39:59 sam Exp $
+ * $Id: esd.c,v 1.11 2002/08/29 23:53:22 massiot Exp $
  *
  * Authors: Samuel Hocevar <sam@zoy.org>
  *
@@ -91,7 +91,8 @@ static int Open( vlc_object_t *p_this )
 
     /* Create ESD thread and wait for its readiness. */
     p_sys->b_initialized = VLC_FALSE;
-    if( vlc_thread_create( p_aout, "aout", ESDThread, VLC_FALSE ) )
+    if( vlc_thread_create( p_aout, "aout", ESDThread,
+                           VLC_THREAD_PRIORITY_OUTPUT, VLC_FALSE ) )
     {
         msg_Err( p_aout, "cannot create ESD thread (%s)", strerror(errno) );
         free( p_sys );
index 111e408..4cc278e 100644 (file)
@@ -2,7 +2,7 @@
  * oss.c : OSS /dev/dsp module for vlc
  *****************************************************************************
  * Copyright (C) 2000-2002 VideoLAN
- * $Id: oss.c,v 1.19 2002/08/25 16:55:55 sam Exp $
+ * $Id: oss.c,v 1.20 2002/08/29 23:53:22 massiot Exp $
  *
  * Authors: Michel Kaempf <maxx@via.ecp.fr>
  *          Samuel Hocevar <sam@zoy.org>
@@ -131,7 +131,8 @@ static int Open( vlc_object_t *p_this )
 
     /* Create OSS thread and wait for its readiness. */
     p_sys->b_initialized = VLC_FALSE;
-    if( vlc_thread_create( p_aout, "aout", OSSThread, VLC_FALSE ) )
+    if( vlc_thread_create( p_aout, "aout", OSSThread,
+                           VLC_THREAD_PRIORITY_OUTPUT, VLC_FALSE ) )
     {
         msg_Err( p_aout, "cannot create OSS thread (%s)", strerror(errno) );
         close( p_sys->i_fd );
index 96397f4..2ff275b 100644 (file)
@@ -2,7 +2,7 @@
  * video_decoder.c : video decoder thread
  *****************************************************************************
  * Copyright (C) 1999-2001 VideoLAN
- * $Id: decoder.c,v 1.3 2002/08/08 00:35:11 sam Exp $
+ * $Id: decoder.c,v 1.4 2002/08/29 23:53:22 massiot Exp $
  *
  * Authors: Christophe Massiot <massiot@via.ecp.fr>
  *          Michel Lespinasse <walken@zoy.org>
@@ -71,7 +71,8 @@ vdec_thread_t * vdec_CreateThread( vdec_pool_t * p_pool )
     p_vdec->p_pool = p_pool;
 
     /* Spawn the video decoder thread */
-    if( vlc_thread_create( p_vdec, "video decoder", RunThread, 0 ) )
+    if( vlc_thread_create( p_vdec, "video decoder", RunThread,
+                           VLC_THREAD_PRIORITY_LOW, VLC_FALSE ) )
     {
         msg_Err( p_vdec, "cannot spawn video decoder thread" );
         vlc_object_destroy( p_vdec );
index a98fed7..01a1d26 100644 (file)
@@ -2,7 +2,7 @@
  * aout.cpp: BeOS audio output
  *****************************************************************************
  * Copyright (C) 1999, 2000, 2001 VideoLAN
- * $Id: AudioOutput.cpp,v 1.5 2002/08/23 14:16:23 tcastley Exp $
+ * $Id: AudioOutput.cpp,v 1.6 2002/08/29 23:53:22 massiot Exp $
  *
  * Authors: Jean-Marc Dressler <polux@via.ecp.fr>
  *          Samuel Hocevar <sam@zoy.org>
@@ -105,9 +105,10 @@ int E_(OpenAudio) ( vlc_object_t * p_this )
         return -1;
     }
 
-    if( vlc_thread_create( p_aout, "aout", BeOSThread, VLC_FALSE) )
+    if( vlc_thread_create( p_aout, "aout", BeOSThread,
+                           VLC_THREAD_PRIORITY_OUTPUT, VLC_FALSE ) )
     {
-        msg_Err( p_aout, "cannot create OSS thread " );
+        msg_Err( p_aout, "cannot create aout thread" );
         delete p_sys->p_sound;
         free( p_sys->p_format );
         free( p_sys );
@@ -278,4 +279,5 @@ static int BeOSThread( aout_instance_t * p_aout )
     
     return 0;
 
-}
\ No newline at end of file
+}
+
index 33c9623..15871a6 100644 (file)
@@ -104,7 +104,8 @@ int E_(OpenAudio)( vlc_object_t *p_this )
 
     /* Create audio thread and wait for its readiness. */
     p_aout->output.p_sys->b_initialized = VLC_FALSE;
-    if( vlc_thread_create( p_aout, "aout", QNXaoutThread, VLC_FALSE ) )
+    if( vlc_thread_create( p_aout, "aout", QNXaoutThread,
+                           VLC_THREAD_PRIORITY_OUTPUT, VLC_FALSE ) )
     {
         msg_Err( p_aout, "cannot create QNX audio thread (%s)", strerror(errno) );
         E_(CloseAudio)( p_this );
index ba05ec9..583a536 100644 (file)
@@ -2,7 +2,7 @@
  * gtk_main.c : Gtk+ wrapper for gtk_main
  *****************************************************************************
  * Copyright (C) 2002 VideoLAN
- * $Id: gtk_main.c,v 1.4 2002/08/21 17:31:58 sam Exp $
+ * $Id: gtk_main.c,v 1.5 2002/08/29 23:53:22 massiot Exp $
  *
  * Authors: Samuel Hocevar <sam@zoy.org>
  *
@@ -98,7 +98,8 @@ static int Open( vlc_object_t *p_this )
 
     /* Launch the gtk_main() thread. It will not return until it has
      * called gdk_threads_enter(), which ensures us thread safety. */
-    if( vlc_thread_create( p_gtk_main, "gtk_main", GtkMain, VLC_TRUE ) )
+    if( vlc_thread_create( p_gtk_main, "gtk_main", GtkMain,
+                           VLC_THREAD_PRIORITY_LOW, VLC_TRUE ) )
     {
         vlc_object_destroy( p_gtk_main );
         i_refcount--;
index 4ef9b8b..5092044 100644 (file)
@@ -2,7 +2,7 @@
  * aout.c: Windows DirectX audio output method
  *****************************************************************************
  * Copyright (C) 2001 VideoLAN
- * $Id: aout.c,v 1.7 2002/08/25 09:40:00 sam Exp $
+ * $Id: aout.c,v 1.8 2002/08/29 23:53:22 massiot Exp $
  *
  * Authors: Gildas Bazin <gbazin@netcourrier.com>
  *
@@ -175,7 +175,7 @@ int E_(OpenAudio) ( vlc_object_t *p_this )
     msg_Dbg( p_aout, "creating DirectSoundThread" );
     if( vlc_thread_create( p_aout->output.p_sys->p_notif,
                            "DirectSound Notification Thread",
-                           DirectSoundThread, 1 ) )
+                           DirectSoundThread, VLC_THREAD_PRIORITY_OUTPUT, 1 ) )
     {
         msg_Err( p_aout, "cannot create DirectSoundThread" );
         goto error;
index bd4608b..e0404f6 100644 (file)
@@ -2,7 +2,7 @@
  * vout.c: Windows DirectX video output display method
  *****************************************************************************
  * Copyright (C) 2001 VideoLAN
- * $Id: vout.c,v 1.2 2002/08/12 09:34:15 sam Exp $
+ * $Id: vout.c,v 1.3 2002/08/29 23:53:22 massiot Exp $
  *
  * Authors: Gildas Bazin <gbazin@netcourrier.com>
  *
@@ -140,7 +140,8 @@ int E_(OpenVideo) ( vlc_object_t *p_this )
         vlc_object_create( p_vout, sizeof(event_thread_t) );
     p_vout->p_sys->p_event->p_vout = p_vout;
     if( vlc_thread_create( p_vout->p_sys->p_event,
-                           "DirectX Events Thread", DirectXEventThread, 1 ) )
+                           "DirectX Events Thread", DirectXEventThread,
+                           VLC_THREAD_PRIORITY_LOW 1 ) )
     {
         msg_Err( p_vout, "cannot create DirectXEventThread" );
         vlc_object_destroy( p_vout->p_sys->p_event );
index 189f545..42d5f96 100644 (file)
@@ -4,7 +4,7 @@
  * decoders.
  *****************************************************************************
  * Copyright (C) 1998-2002 VideoLAN
- * $Id: input.c,v 1.211 2002/08/16 12:31:04 sam Exp $
+ * $Id: input.c,v 1.212 2002/08/29 23:53:22 massiot Exp $
  *
  * Authors: Christophe Massiot <massiot@via.ecp.fr>
  *
@@ -158,7 +158,8 @@ input_thread_t *__input_CreateThread( vlc_object_t *p_parent,
     vlc_object_attach( p_input, p_parent );
 
     /* Create thread and wait for its readiness. */
-    if( vlc_thread_create( p_input, "input", RunThread, VLC_TRUE ) )
+    if( vlc_thread_create( p_input, "input", RunThread,
+                           VLC_THREAD_PRIORITY_INPUT, VLC_TRUE ) )
     {
         msg_Err( p_input, "cannot create input thread (%s)", strerror(errno) );
         free( p_input );
index 215d725..dd03a46 100644 (file)
@@ -2,7 +2,7 @@
  * input_dec.c: Functions for the management of decoders
  *****************************************************************************
  * Copyright (C) 1999-2001 VideoLAN
- * $Id: input_dec.c,v 1.45 2002/08/12 22:12:51 massiot Exp $
+ * $Id: input_dec.c,v 1.46 2002/08/29 23:53:22 massiot Exp $
  *
  * Authors: Christophe Massiot <massiot@via.ecp.fr>
  *
@@ -46,6 +46,7 @@ decoder_fifo_t * input_RunDecoder( input_thread_t * p_input,
                                    es_descriptor_t * p_es )
 {
     decoder_fifo_t *p_fifo;
+    int i_priority;
 
     /* Create the decoder configuration structure */
     p_fifo = CreateDecoderFifo( p_input, p_es );
@@ -67,8 +68,18 @@ decoder_fifo_t * input_RunDecoder( input_thread_t * p_input,
         return NULL;
     }
 
+    if ( p_es->i_cat == AUDIO_ES )
+    {
+        i_priority = VLC_THREAD_PRIORITY_AUDIO;
+    }
+    else
+    {
+        i_priority = VLC_THREAD_PRIORITY_LOW;
+    }
+
     /* Spawn the decoder thread */
-    if( vlc_thread_create( p_fifo, "decoder", p_fifo->pf_run, 0 ) )
+    if( vlc_thread_create( p_fifo, "decoder", p_fifo->pf_run,
+                           i_priority, VLC_FALSE ) )
     {
         msg_Err( p_fifo, "cannot spawn decoder thread \"%s\"",
                          p_fifo->p_module->psz_object_name );
index 9a8b418..4314135 100644 (file)
@@ -4,7 +4,7 @@
  * interface, such as command line.
  *****************************************************************************
  * Copyright (C) 1998-2001 VideoLAN
- * $Id: interface.c,v 1.98 2002/08/04 20:04:11 sam Exp $
+ * $Id: interface.c,v 1.99 2002/08/29 23:53:22 massiot Exp $
  *
  * Authors: Vincent Seguin <seguin@via.ecp.fr>
  *
@@ -103,7 +103,8 @@ vlc_error_t intf_RunThread( intf_thread_t *p_intf )
     if( p_intf->b_block )
     {
         /* Run a manager thread, launch the interface, kill the manager */
-        if( vlc_thread_create( p_intf, "manager", Manager, 0 ) )
+        if( vlc_thread_create( p_intf, "manager", Manager,
+                               VLC_THREAD_PRIORITY_LOW, VLC_FALSE ) )
         {
             msg_Err( p_intf, "cannot spawn manager thread" );
             return VLC_EGENERIC;
@@ -118,7 +119,8 @@ vlc_error_t intf_RunThread( intf_thread_t *p_intf )
     else
     {
         /* Run the interface in a separate thread */
-        if( vlc_thread_create( p_intf, "interface", p_intf->pf_run, 0 ) )
+        if( vlc_thread_create( p_intf, "interface", p_intf->pf_run,
+                               VLC_THREAD_PRIORITY_LOW, VLC_FALSE ) )
         {
             msg_Err( p_intf, "cannot spawn interface thread" );
             return VLC_EGENERIC;
index d5fc5f4..72ef7c7 100644 (file)
@@ -2,7 +2,7 @@
  * beos_init.cpp: Initialization for BeOS specific features 
  *****************************************************************************
  * Copyright (C) 1999-2001 VideoLAN
- * $Id: beos_specific.cpp,v 1.24 2002/08/12 09:34:15 sam Exp $
+ * $Id: beos_specific.cpp,v 1.25 2002/08/29 23:53:22 massiot Exp $
  *
  * Authors: Jean-Marc Dressler <polux@via.ecp.fr>
  *
@@ -70,7 +70,8 @@ void system_Init( vlc_t *p_this, int *pi_argc, char *ppsz_argv[] )
             (vlc_object_t *)vlc_object_create( p_this, sizeof(vlc_object_t) );
 
     /* Create the BApplication thread and wait for initialization */
-    vlc_thread_create( p_this->p_vlc->p_appthread, "app thread", AppThread, 1 );
+    vlc_thread_create( p_this->p_vlc->p_appthread, "app thread", AppThread,
+                       VLC_THREAD_PRIORITY_LOW, VLC_TRUE );
 }
 
 /*****************************************************************************
index ac8a3f0..31ba463 100644 (file)
@@ -2,7 +2,7 @@
  * threads.c : threads implementation for the VideoLAN client
  *****************************************************************************
  * Copyright (C) 1999, 2000, 2001, 2002 VideoLAN
- * $Id: threads.c,v 1.12 2002/08/08 00:35:11 sam Exp $
+ * $Id: threads.c,v 1.13 2002/08/29 23:53:22 massiot Exp $
  *
  * Authors: Jean-Marc Dressler <polux@via.ecp.fr>
  *          Samuel Hocevar <sam@zoy.org>
@@ -218,11 +218,13 @@ int __vlc_threads_end( vlc_object_t *p_this )
  *****************************************************************************/
 int __vlc_mutex_init( vlc_object_t *p_this, vlc_mutex_t *p_mutex )
 {
+    p_mutex->p_this = p_this;
+
 #if defined( PTH_INIT_IN_PTH_H )
-    return pth_mutex_init( p_mutex );
+    return pth_mutex_init( &p_mutex->mutex );
 
 #elif defined( ST_INIT_IN_ST_H )
-    *p_mutex = st_mutex_new();
+    *p_mutex->mutex = st_mutex_new();
     return ( *p_mutex == NULL ) ? errno : 0;
 
 #elif defined( WIN32 )
@@ -234,7 +236,7 @@ int __vlc_mutex_init( vlc_object_t *p_this, vlc_mutex_t *p_mutex )
     {
         /* We are running on NT/2K/XP, we can use SignalObjectAndWait */
         p_mutex->mutex = CreateMutex( 0, FALSE, 0 );
-        return ( p_mutex->mutex ? 0 : 1 );
+        return ( p_mutex->mutex != NULL ? 0 : 1 );
     }
     else
     {
@@ -245,24 +247,25 @@ int __vlc_mutex_init( vlc_object_t *p_this, vlc_mutex_t *p_mutex )
 
 #elif defined( PTHREAD_COND_T_IN_PTHREAD_H )
 #   if defined(DEBUG) && defined(SYS_LINUX)
-    /* Create error-checking mutex to detect threads problems more easily. */
-    pthread_mutexattr_t attr;
-    int                 i_result;
-
-    pthread_mutexattr_init( &attr );
-    pthread_mutexattr_setkind_np( &attr, PTHREAD_MUTEX_ERRORCHECK_NP );
-    i_result = pthread_mutex_init( p_mutex, &attr );
-    pthread_mutexattr_destroy( &attr );
-    return( i_result );
+    {
+        /* Create error-checking mutex to detect problems more easily. */
+        pthread_mutexattr_t attr;
+        int                 i_result;
+
+        pthread_mutexattr_init( &attr );
+        pthread_mutexattr_setkind_np( &attr, PTHREAD_MUTEX_ERRORCHECK_NP );
+        i_result = pthread_mutex_init( p_mutex, &attr );
+        pthread_mutexattr_destroy( &attr );
+        return( i_result );
+    }
 #   endif
-    return pthread_mutex_init( p_mutex, NULL );
+    return pthread_mutex_init( &p_mutex->mutex, NULL );
 
 #elif defined( HAVE_CTHREADS_H )
     mutex_init( p_mutex );
     return 0;
 
 #elif defined( HAVE_KERNEL_SCHEDULER_H )
-
     /* check the arguments and whether it's already been initialized */
     if( p_mutex == NULL )
     {
@@ -291,11 +294,16 @@ int __vlc_mutex_init( vlc_object_t *p_this, vlc_mutex_t *p_mutex )
  *****************************************************************************/
 int __vlc_mutex_destroy( char * psz_file, int i_line, vlc_mutex_t *p_mutex )
 {
+    int i_result;
+    /* In case of error : */
+    int i_thread = -1;
+    const char * psz_error = "";
+
 #if defined( PTH_INIT_IN_PTH_H )
     return 0;
 
 #elif defined( ST_INIT_IN_ST_H )
-    return st_mutex_destroy( *p_mutex );
+    i_result = st_mutex_destroy( *p_mutex );
 
 #elif defined( WIN32 )
     if( p_mutex->mutex )
@@ -309,15 +317,12 @@ int __vlc_mutex_destroy( char * psz_file, int i_line, vlc_mutex_t *p_mutex )
     return 0;
 
 #elif defined( PTHREAD_COND_T_IN_PTHREAD_H )    
-    int i_return = pthread_mutex_destroy( p_mutex );
-    if( i_return )
+    i_result = pthread_mutex_destroy( &p_mutex->mutex );
+    if ( i_result )
     {
-#if 0
-        intf_ErrMsg( "thread %d error: mutex_destroy failed at %s:%d (%s)",
-                     pthread_self(), psz_file, i_line, strerror(i_return) );
-#endif
+        i_thread = pthread_self();
+        psz_error = strerror(i_result);
     }
-    return i_return;
 
 #elif defined( HAVE_CTHREADS_H )
     return 0;
@@ -330,8 +335,15 @@ int __vlc_mutex_destroy( char * psz_file, int i_line, vlc_mutex_t *p_mutex )
 
     p_mutex->init = 0;
     return B_OK;
-
 #endif    
+
+    if( i_result )
+    {
+        msg_Err( p_mutex->p_this,
+                 "thread %d: mutex_destroy failed at %s:%d (%d:%s)",
+                 i_thread, psz_file, i_line, i_result, psz_error );
+    }
+    return i_result;
 }
 
 /*****************************************************************************
@@ -339,12 +351,14 @@ int __vlc_mutex_destroy( char * psz_file, int i_line, vlc_mutex_t *p_mutex )
  *****************************************************************************/
 int __vlc_cond_init( vlc_object_t *p_this, vlc_cond_t *p_condvar )
 {
+    p_condvar->p_this = p_this;
+
 #if defined( PTH_INIT_IN_PTH_H )
-    return pth_cond_init( p_condvar );
+    return pth_cond_init( &p_condvar->cond );
 
 #elif defined( ST_INIT_IN_ST_H )
-    *p_condvar = st_cond_new();
-    return ( *p_condvar == NULL ) ? errno : 0;
+    *p_condvar->cond = st_cond_new();
+    return ( *p_condvar->cond == NULL ) ? errno : 0;
 
 #elif defined( WIN32 )
     /* Initialize counter */
@@ -385,7 +399,7 @@ int __vlc_cond_init( vlc_object_t *p_this, vlc_cond_t *p_condvar )
     }
 
 #elif defined( PTHREAD_COND_T_IN_PTHREAD_H )
-    return pthread_cond_init( p_condvar, NULL );
+    return pthread_cond_init( &p_condvar->cond, NULL );
 
 #elif defined( HAVE_CTHREADS_H )
     /* condition_init() */
@@ -410,7 +424,6 @@ int __vlc_cond_init( vlc_object_t *p_this, vlc_cond_t *p_condvar )
     p_condvar->thread = -1;
     p_condvar->init = 9999;
     return 0;
-
 #endif
 }
 
@@ -419,29 +432,31 @@ int __vlc_cond_init( vlc_object_t *p_this, vlc_cond_t *p_condvar )
  *****************************************************************************/
 int __vlc_cond_destroy( char * psz_file, int i_line, vlc_cond_t *p_condvar )
 {
+    int i_result;
+    /* In case of error : */
+    int i_thread = -1;
+    const char * psz_error = "";
+
 #if defined( PTH_INIT_IN_PTH_H )
     return 0;
 
 #elif defined( ST_INIT_IN_ST_H )
-    return st_cond_destroy( *p_condvar );
+    i_result = st_cond_destroy( *p_condvar->cond );
 
 #elif defined( WIN32 )
     if( !p_condvar->semaphore )
-        return !CloseHandle( p_condvar->event );
+        i_result = !CloseHandle( p_condvar->event );
     else
-        return !CloseHandle( p_condvar->event )
+        i_result = !CloseHandle( p_condvar->event )
           || !CloseHandle( p_condvar->semaphore );
 
 #elif defined( PTHREAD_COND_T_IN_PTHREAD_H )
-    int i_result = pthread_cond_destroy( p_condvar );
-    if( i_result )
+    i_result = pthread_cond_destroy( &p_condvar->cond );
+    if ( i_result )
     {
-#if 0
-        intf_ErrMsg( "thread %d error: cond_destroy failed at %s:%d (%s)",
-                     pthread_self(), psz_file, i_line, strerror(i_result) );
-#endif
+        i_thread = pthread_self();
+        psz_error = strerror(i_result);
     }
-    return i_result;
 
 #elif defined( HAVE_CTHREADS_H )
     return 0;
@@ -449,16 +464,26 @@ int __vlc_cond_destroy( char * psz_file, int i_line, vlc_cond_t *p_condvar )
 #elif defined( HAVE_KERNEL_SCHEDULER_H )
     p_condvar->init = 0;
     return 0;
+#endif
 
-#endif    
+    if( i_result )
+    {
+        msg_Err( p_condvar->p_this,
+                 "thread %d: cond_destroy failed at %s:%d (%d:%s)",
+                 i_thread, psz_file, i_line, i_result, psz_error );
+    }
+    return i_result;
 }
 
 /*****************************************************************************
  * vlc_thread_create: create a thread, inner version
+ *****************************************************************************
+ * Note that i_priority is only taken into account on platforms supporting
+ * userland real-time priority threads.
  *****************************************************************************/
 int __vlc_thread_create( vlc_object_t *p_this, char * psz_file, int i_line,
                          char *psz_name, void * ( *func ) ( void * ),
-                         vlc_bool_t b_wait )
+                         int i_priority, vlc_bool_t b_wait )
 {
     int i_ret;
 
@@ -500,11 +525,32 @@ int __vlc_thread_create( vlc_object_t *p_this, char * psz_file, int i_line,
                                         (void *)p_this, 0, &threadID );
     }
 
+    if ( p_this->thread_id && i_priority )
+    {
+        if ( !SetThreadPriority(p_this->thread_id, i_priority) )
+        {
+            msg_Warn( p_this, "couldn't set a faster priority" );
+            i_priority = 0;
+        }
+    }
+
     i_ret = ( p_this->thread_id ? 0 : 1 );
 
 #elif defined( PTHREAD_COND_T_IN_PTHREAD_H )
     i_ret = pthread_create( &p_this->thread_id, NULL, func, (void *)p_this );
 
+    if ( i_priority )
+    {
+        struct sched_param param;
+        memset( &param, 0, sizeof(struct sched_param) );
+        param.sched_priority = i_priority;
+        if ( pthread_setschedparam( p_this->thread_id, SCHED_RR, &param ) )
+        {
+            msg_Warn( p_this, "couldn't go to real-time priority" );
+            i_priority = 0;
+        }
+    }
+
 #elif defined( HAVE_CTHREADS_H )
     p_this->thread_id = cthread_fork( (cthread_fn_t)func, (any_t)p_this );
     i_ret = 0;
@@ -537,8 +583,9 @@ int __vlc_thread_create( vlc_object_t *p_this, char * psz_file, int i_line,
 
         p_this->b_thread = 1;
 
-        msg_Dbg( p_this, "thread %d (%s) created (%s:%d)",
-                         p_this->thread_id, psz_name, psz_file, i_line );
+        msg_Dbg( p_this, "thread %d (%s) created at priority %d (%s:%d)",
+                 p_this->thread_id, psz_name, i_priority,
+                 psz_file, i_line );
 
         vlc_mutex_unlock( &p_this->object_lock );
     }
index 81935cc..9eca212 100644 (file)
@@ -2,7 +2,7 @@
  * playlist.c : Playlist management functions
  *****************************************************************************
  * Copyright (C) 1999-2001 VideoLAN
- * $Id: playlist.c,v 1.12 2002/08/25 19:27:20 sam Exp $
+ * $Id: playlist.c,v 1.13 2002/08/29 23:53:22 massiot Exp $
  *
  * Authors: Samuel Hocevar <sam@zoy.org>
  *
@@ -67,7 +67,8 @@ playlist_t * __playlist_Create ( vlc_object_t *p_parent )
     p_playlist->i_size = 0;
     p_playlist->pp_items = NULL;
 
-    if( vlc_thread_create( p_playlist, "playlist", RunThread, VLC_TRUE ) )
+    if( vlc_thread_create( p_playlist, "playlist", RunThread,
+                           VLC_THREAD_PRIORITY_LOW, VLC_TRUE ) )
     {
         msg_Err( p_playlist, "cannot spawn playlist thread" );
         vlc_object_destroy( p_playlist );
index b661c15..f2fb320 100644 (file)
@@ -5,7 +5,7 @@
  * thread, and destroy a previously oppened video output thread.
  *****************************************************************************
  * Copyright (C) 2000-2001 VideoLAN
- * $Id: video_output.c,v 1.190 2002/08/12 09:34:15 sam Exp $
+ * $Id: video_output.c,v 1.191 2002/08/29 23:53:22 massiot Exp $
  *
  * Authors: Vincent Seguin <seguin@via.ecp.fr>
  *
@@ -202,7 +202,8 @@ vout_thread_t * __vout_CreateThread ( vlc_object_t *p_parent,
 
     vlc_object_attach( p_vout, p_parent );
 
-    if( vlc_thread_create( p_vout, "video output", RunThread, 0 ) )
+    if( vlc_thread_create( p_vout, "video output", RunThread,
+                           VLC_THREAD_PRIORITY_OUTPUT, VLC_FALSE ) )
     {
         msg_Err( p_vout, "%s", strerror(ENOMEM) );
         module_Unneed( p_vout, p_vout->p_module );