X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=src%2Fmisc%2Fthreads.c;h=36c4d3d849d69eaac070d98a9ec967bd7fd761ba;hb=6846b211d29a865f8a8f43af253f2732529a51a1;hp=5141bd56bac05376400b79dd33154ed6cff67072;hpb=be8ca6e9a9924ccdf8c72449b85bdb97e05e87a6;p=vlc diff --git a/src/misc/threads.c b/src/misc/threads.c index 5141bd56ba..36c4d3d849 100644 --- a/src/misc/threads.c +++ b/src/misc/threads.c @@ -2,7 +2,7 @@ * threads.c : threads implementation for the VideoLAN client ***************************************************************************** * Copyright (C) 1999, 2000, 2001, 2002 VideoLAN - * $Id: threads.c,v 1.24 2002/11/10 18:04:24 sam Exp $ + * $Id: threads.c,v 1.29 2002/12/14 19:19:08 gbazin Exp $ * * Authors: Jean-Marc Dressler * Samuel Hocevar @@ -12,7 +12,7 @@ * 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 @@ -39,6 +39,7 @@ static volatile int i_initializations = 0; #if defined( PTH_INIT_IN_PTH_H ) #elif defined( ST_INIT_IN_ST_H ) +#elif defined( UNDER_CE ) #elif defined( WIN32 ) #elif defined( PTHREAD_COND_T_IN_PTHREAD_H ) static pthread_mutex_t once_mutex = PTHREAD_MUTEX_INITIALIZER; @@ -77,6 +78,7 @@ int __vlc_threads_init( vlc_object_t *p_this ) * hope nothing wrong happens. */ #if defined( PTH_INIT_IN_PTH_H ) #elif defined( ST_INIT_IN_ST_H ) +#elif defined( UNDER_CE ) #elif defined( WIN32 ) HINSTANCE hInstLib; #elif defined( PTHREAD_COND_T_IN_PTHREAD_H ) @@ -150,6 +152,8 @@ int __vlc_threads_init( vlc_object_t *p_this ) while( i_status == VLC_THREADS_PENDING ) msleep( THREAD_SLEEP ); #elif defined( ST_INIT_IN_ST_H ) while( i_status == VLC_THREADS_PENDING ) msleep( THREAD_SLEEP ); +#elif defined( UNDER_CE ) + while( i_status == VLC_THREADS_PENDING ) msleep( THREAD_SLEEP ); #elif defined( WIN32 ) while( i_status == VLC_THREADS_PENDING ) msleep( THREAD_SLEEP ); #elif defined( PTHREAD_COND_T_IN_PTHREAD_H ) @@ -186,6 +190,9 @@ int __vlc_threads_end( vlc_object_t *p_this ) #elif defined( ST_INIT_IN_ST_H ) i_initializations--; +#elif defined( UNDER_CE ) + i_initializations--; + #elif defined( WIN32 ) i_initializations--; @@ -211,7 +218,7 @@ int __vlc_threads_end( vlc_object_t *p_this ) /* Wrapper function for profiling */ static void * vlc_thread_wrapper ( void *p_wrapper ); -# ifdef WIN32 +# if defined( WIN32 ) && !defined( UNDER_CE ) # define ITIMER_REAL 1 # define ITIMER_PROF 2 @@ -220,24 +227,24 @@ struct itimerval { struct timeval it_value; struct timeval it_interval; -}; +}; int setitimer(int kind, const struct itimerval* itnew, struct itimerval* itold); -# endif /* WIN32 */ +# endif /* WIN32 && !UNDER_CE */ typedef struct wrapper_t { /* Data lock access */ vlc_mutex_t lock; vlc_cond_t wait; - + /* Data used to spawn the real thread */ vlc_thread_func_t func; void *p_data; - + /* Profiling timer passed to the thread */ struct itimerval itimer; - + } wrapper_t; #endif /* GPROF */ @@ -256,12 +263,15 @@ int __vlc_mutex_init( vlc_object_t *p_this, vlc_mutex_t *p_mutex ) p_mutex->mutex = st_mutex_new(); return ( p_mutex->mutex == NULL ) ? errno : 0; +#elif defined( UNDER_CE ) + InitializeCriticalSection( &p_mutex->csection ); + return 0; + #elif defined( WIN32 ) /* We use mutexes on WinNT/2K/XP because we can use the SignalObjectAndWait * function and have a 100% correct vlc_cond_wait() implementation. * As this function is not available on Win9x, we can use the faster * CriticalSections */ -# if !defined( UNDER_CE ) if( p_this->p_libvlc->SignalObjectAndWait && !p_this->p_libvlc->b_fast_mutex ) { @@ -270,7 +280,6 @@ int __vlc_mutex_init( vlc_object_t *p_this, vlc_mutex_t *p_mutex ) return ( p_mutex->mutex != NULL ? 0 : 1 ); } else -# endif { p_mutex->mutex = NULL; InitializeCriticalSection( &p_mutex->csection ); @@ -337,6 +346,10 @@ int __vlc_mutex_destroy( char * psz_file, int i_line, vlc_mutex_t *p_mutex ) #elif defined( ST_INIT_IN_ST_H ) i_result = st_mutex_destroy( p_mutex->mutex ); +#elif defined( UNDER_CE ) + DeleteCriticalSection( &p_mutex->csection ); + return 0; + #elif defined( WIN32 ) if( p_mutex->mutex ) { @@ -348,7 +361,7 @@ 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 ) +#elif defined( PTHREAD_COND_T_IN_PTHREAD_H ) i_result = pthread_mutex_destroy( &p_mutex->mutex ); if ( i_result ) { @@ -367,7 +380,7 @@ int __vlc_mutex_destroy( char * psz_file, int i_line, vlc_mutex_t *p_mutex ) p_mutex->init = 0; return B_OK; -#endif +#endif if( i_result ) { @@ -392,11 +405,21 @@ int __vlc_cond_init( vlc_object_t *p_this, vlc_cond_t *p_condvar ) p_condvar->cond = st_cond_new(); return ( p_condvar->cond == NULL ) ? errno : 0; +#elif defined( UNDER_CE ) + /* Initialize counter */ + p_condvar->i_waiting_threads = 0; + + /* Create an auto-reset event. */ + p_condvar->event = CreateEvent( NULL, /* no security */ + FALSE, /* auto-reset event */ + FALSE, /* start non-signaled */ + NULL ); /* unnamed */ + return !p_condvar->event; + #elif defined( WIN32 ) /* Initialize counter */ p_condvar->i_waiting_threads = 0; -# if !defined( UNDER_CE ) /* Misc init */ p_condvar->i_win9x_cv = p_this->p_libvlc->i_win9x_cv; p_condvar->SignalObjectAndWait = p_this->p_libvlc->SignalObjectAndWait; @@ -404,7 +427,6 @@ int __vlc_cond_init( vlc_object_t *p_this, vlc_cond_t *p_condvar ) if( (p_condvar->SignalObjectAndWait && !p_this->p_libvlc->b_fast_mutex) || p_condvar->i_win9x_cv == 0 ) { -# endif /* Create an auto-reset event. */ p_condvar->event = CreateEvent( NULL, /* no security */ FALSE, /* auto-reset event */ @@ -413,7 +435,6 @@ int __vlc_cond_init( vlc_object_t *p_this, vlc_cond_t *p_condvar ) p_condvar->semaphore = NULL; return !p_condvar->event; -# if !defined( UNDER_CE ) } else { @@ -433,7 +454,6 @@ int __vlc_cond_init( vlc_object_t *p_this, vlc_cond_t *p_condvar ) return !p_condvar->semaphore || !p_condvar->event; } -# endif #elif defined( PTHREAD_COND_T_IN_PTHREAD_H ) return pthread_cond_init( &p_condvar->cond, NULL ); @@ -480,6 +500,9 @@ int __vlc_cond_destroy( char * psz_file, int i_line, vlc_cond_t *p_condvar ) #elif defined( ST_INIT_IN_ST_H ) i_result = st_cond_destroy( p_condvar->cond ); +#elif defined( UNDER_CE ) + i_result = !CloseHandle( p_condvar->event ); + #elif defined( WIN32 ) if( !p_condvar->semaphore ) i_result = !CloseHandle( p_condvar->event ); @@ -550,16 +573,22 @@ int __vlc_thread_create( vlc_object_t *p_this, char * psz_file, int i_line, #elif defined( ST_INIT_IN_ST_H ) p_this->thread_id = st_thread_create( func, (void *)p_this, 1, 0 ); i_ret = 0; - -#elif defined( WIN32 ) + +#elif defined( WIN32 ) || defined( UNDER_CE ) { unsigned threadID; /* When using the MSVCRT C library you have to use the _beginthreadex * function instead of CreateThread, otherwise you'll end up with - * memory leaks and the signal functions not working */ + * memory leaks and the signal functions not working (see Microsoft + * Knowledge Base, article 104641) */ p_this->thread_id = - (HANDLE)_beginthreadex( NULL, 0, (PTHREAD_START) func, +#if defined( UNDER_CE ) + (HANDLE)CreateThread( NULL, 0, (PTHREAD_START) func, + (void *)p_this, 0, &threadID ); +#else + (HANDLE)_beginthreadex( NULL, 0, (PTHREAD_START) func, (void *)p_this, 0, &threadID ); +#endif } if ( p_this->thread_id && i_priority ) @@ -583,7 +612,8 @@ int __vlc_thread_create( vlc_object_t *p_this, char * psz_file, int i_line, param.sched_priority = i_priority; if ( pthread_setschedparam( p_this->thread_id, SCHED_RR, ¶m ) ) { - msg_Warn( p_this, "couldn't go to real-time priority" ); + msg_Warn( p_this, "couldn't go to real-time priority (%s:%d)", + psz_file, i_line ); i_priority = 0; } } @@ -628,14 +658,54 @@ int __vlc_thread_create( vlc_object_t *p_this, char * psz_file, int i_line, } else { +#ifdef HAVE_STRERROR msg_Err( p_this, "%s thread could not be created at %s:%d (%s)", psz_name, psz_file, i_line, strerror(i_ret) ); +#else + msg_Err( p_this, "%s thread could not be created at %s:%d", + psz_name, psz_file, i_line ); +#endif vlc_mutex_unlock( &p_this->object_lock ); } return i_ret; } +/***************************************************************************** + * vlc_thread_set_priority: set the priority of the current thread when we + * couldn't set it in vlc_thread_create (for instance for the main thread) + *****************************************************************************/ +int __vlc_thread_set_priority( vlc_object_t *p_this, char * psz_file, + int i_line, int i_priority ) +{ +#if defined( WIN32 ) || defined( UNDER_CE ) + if ( !SetThreadPriority(GetCurrentThread(), i_priority) ) + { + msg_Warn( p_this, "couldn't set a faster priority" ); + return 1; + } + +#elif defined( PTHREAD_COND_T_IN_PTHREAD_H ) + if ( i_priority ) + { + struct sched_param param; + memset( ¶m, 0, sizeof(struct sched_param) ); + param.sched_priority = i_priority; + if ( pthread_setschedparam( pthread_self(), SCHED_RR, ¶m ) ) + { + msg_Warn( p_this, "couldn't go to real-time priority (%s:%d)", + psz_file, i_line ); + return 1; + } + } + +#else + return 1; +#endif + + return 0; +} + /***************************************************************************** * vlc_thread_ready: tell the parent thread we were successfully spawned *****************************************************************************/ @@ -658,7 +728,10 @@ void __vlc_thread_join( vlc_object_t *p_this, char * psz_file, int i_line ) #elif defined( ST_INIT_IN_ST_H ) i_ret = st_thread_join( p_this->thread_id, NULL ); - + +#elif defined( UNDER_CE ) + WaitForSingleObject( p_this->thread_id, INFINITE ); + #elif defined( WIN32 ) WaitForSingleObject( p_this->thread_id, INFINITE ); @@ -677,8 +750,13 @@ void __vlc_thread_join( vlc_object_t *p_this, char * psz_file, int i_line ) if( i_ret ) { +#ifdef HAVE_STRERROR msg_Err( p_this, "thread_join(%d) failed at %s:%d (%s)", p_this->thread_id, psz_file, i_line, strerror(i_ret) ); +#else + msg_Err( p_this, "thread_join(%d) failed at %s:%d", + p_this->thread_id, psz_file, i_line ); +#endif } else {