]> git.sesse.net Git - vlc/commitdiff
* ./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 3c991f215327ab337a4b3fa41d803f14da9b0378..0ac4fbc7ebec9619eaad720787d4718fccc73fce 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 27be11e6569c1d67bcfe1e52ded2e1a2d02622ba..25f537e413dd543efeed6bd47293336c868d9577 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 6c8e1cfc56dbe2c45f245774ddf77963cffe7bc7..b919b2432d42bd0832dcf55ab1f2b7d9cf2cf49c 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 d27a67b6be56131fd871c7c9ecffda8754dd9eb9..0783051e040c9ca2f73397e0fe7ce59238c66bef 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 537f84c4ada22b55e3a8ba7bc83aa2465135c437..cae6d407481ec14e799995e2af40a4853364c783 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 570243f7b0fd903da3e7f72d74affb397cd81e8c..05639dd3a061c0ab7052bc30c502755740c81190 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 58366043e071e1389e2e9e5a35a0f2581cf4ecd1..4cda186a33d3fcac467686eb68c577b94728b62f 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 9dcaf75bfd68680897b426faca86d795807df9a2..abbd83ee984f1890888928569ef4c3eb005fdb83 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 3324ea8bca12c75fa5a38968aa6b33abfd7f5613..bcec9e62fe6ec43b154320bc9e2bae1c182e4496 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 b74d3d566415c61432fc72089cd48376a6c9edd4..07956c8152256b5171c34b95c81c13233ec88037 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 7e5ca61eace876a73727422e68fe82f77bc915c1..26a589f3c94f7e70a05762e1e1426d6df2c156ce 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 5508b1f09a5c5566c183bd01ff1e8920a2673148..2785610d3ee65f4e0de1c30ced5ae1420879fa20 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 38a3d4a088755c64b8106d467b53dae3554e14bb..319acf62906317dafaab1dd6ea4b93fb02c9ccf4 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 111e408e87269c8e1e9356a6a3c3d7e1029f3b2a..4cc278ed855af7e51ba48aa60f6aed94a0cbc487 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 96397f48228f1b3cedfd4b1d1ad548fc487d55c9..2ff275bed8e2915356c047c5b8ac5ae23562af8f 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 a98fed79058673322fb8d74cf3b9c0d2d8ae29bb..01a1d26d8fbd203e85a5727f287ba495475ab4fc 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 33c96232fcd67fa90dd8bd612ce400f82c441ed6..15871a6241d8f173866a88dd246a44fbf8bb7c30 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 ba05ec959579eb8ffeb3ea8405ceba7125acc6f3..583a536ff7f7e0349525f210783c14921b76e3d2 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 4ef9b8b8a6e3281e879fa21e82f25ea4095731e1..509204418557847dd608d09dedbdbc9f03123cd0 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 bd4608b1ab34f4bc14a080b8596169c9bc3f4307..e0404f6f8ebc495bfe313a5eb3d5f16f6a094690 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 189f545037193dbcfbae6a561c8173bba9c26e4b..42d5f9615b265cf7da3ca0b560d96548e75b8122 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 215d7259f5ac8e129103e8b2164638592bfc33dd..dd03a46225103dab7bac3a4f4879a4bcd95246be 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 9a8b4184ee6f2a5f7663a8f18fe70537bc2ac1fa..4314135eeb0f42eb1cc6b06ff104123f1ad96696 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 d5fc5f4fa0d1c32d7df95d72e827dfefdb7c7fab..72ef7c7226ee3b9f1b03a2edfe7a8785706d3570 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 ac8a3f008ac0e7352a87595af1f74aa6b348a736..31ba463b8014738e2669967010f08e54464f10b6 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 81935ccec8ca8cd9bee9994dfaec148fcef57a0f..9eca212647f4b16e31e57089a61a3b4ddd417ce8 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 b661c159491f1d50092e60fe535cf7a6c07603df..f2fb320576478b288524e9391672843dee0ed9c0 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 );