⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 threads.c

📁 video linux conference
💻 C
📖 第 1 页 / 共 2 页
字号:
/***************************************************************************** * threads.c : threads implementation for the VideoLAN client ***************************************************************************** * Copyright (C) 1999-2004 VideoLAN * $Id: threads.c 10706 2005-04-16 12:30:45Z courmisch $ * * Authors: Jean-Marc Dressler <polux@via.ecp.fr> *          Samuel Hocevar <sam@zoy.org> *          Gildas Bazin <gbazin@netcourrier.com> * * 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. *****************************************************************************/#include <vlc/vlc.h>#include <stdlib.h>#define VLC_THREADS_UNINITIALIZED  0#define VLC_THREADS_PENDING        1#define VLC_THREADS_ERROR          2#define VLC_THREADS_READY          3/***************************************************************************** * Global mutex for lazy initialization of the threads system *****************************************************************************/static volatile unsigned i_initializations = 0;static volatile int i_status = VLC_THREADS_UNINITIALIZED;static vlc_object_t *p_root;#if defined( PTH_INIT_IN_PTH_H )#elif defined( ST_INIT_IN_ST_H )#elif defined( UNDER_CE )#elif defined( WIN32 )#elif defined( HAVE_KERNEL_SCHEDULER_H )#elif defined( PTHREAD_COND_T_IN_PTHREAD_H )    static pthread_mutex_t once_mutex = PTHREAD_MUTEX_INITIALIZER;#elif defined( HAVE_CTHREADS_H )#endif/***************************************************************************** * Global variable for named mutexes *****************************************************************************/typedef struct vlc_namedmutex_t vlc_namedmutex_t;struct vlc_namedmutex_t{    vlc_mutex_t lock;    char *psz_name;    int i_usage;    vlc_namedmutex_t *p_next;};/***************************************************************************** * vlc_threads_init: initialize threads system ***************************************************************************** * This function requires lazy initialization of a global lock in order to * keep the library really thread-safe. Some architectures don't support this * and thus do not guarantee the complete reentrancy. *****************************************************************************/int __vlc_threads_init( vlc_object_t *p_this ){    libvlc_t *p_libvlc = (libvlc_t *)p_this;    int i_ret = VLC_SUCCESS;    /* If we have lazy mutex initialization, use it. Otherwise, we just     * 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 )#elif defined( HAVE_KERNEL_SCHEDULER_H )#elif defined( PTHREAD_COND_T_IN_PTHREAD_H )    pthread_mutex_lock( &once_mutex );#elif defined( HAVE_CTHREADS_H )#endif    if( i_status == VLC_THREADS_UNINITIALIZED )    {        i_status = VLC_THREADS_PENDING;        /* We should be safe now. Do all the initialization stuff we want. */        p_libvlc->b_ready = VLC_FALSE;#if defined( PTH_INIT_IN_PTH_H )        i_ret = ( pth_init() == FALSE );#elif defined( ST_INIT_IN_ST_H )        i_ret = st_init();#elif defined( UNDER_CE )        /* Nothing to initialize */#elif defined( WIN32 )        /* Dynamically get the address of SignalObjectAndWait */        if( GetVersion() < 0x80000000 )        {            HINSTANCE hInstLib;            /* We are running on NT/2K/XP, we can use SignalObjectAndWait */            hInstLib = LoadLibrary( "kernel32" );            if( hInstLib )            {                p_libvlc->SignalObjectAndWait =                    (SIGNALOBJECTANDWAIT)GetProcAddress( hInstLib,                                                     "SignalObjectAndWait" );            }        }        else        {            p_libvlc->SignalObjectAndWait = NULL;        }        p_libvlc->b_fast_mutex = 0;        p_libvlc->i_win9x_cv = 0;#elif defined( HAVE_KERNEL_SCHEDULER_H )#elif defined( PTHREAD_COND_T_IN_PTHREAD_H )#elif defined( HAVE_CTHREADS_H )#endif        p_root = vlc_object_create( p_libvlc, VLC_OBJECT_ROOT );        if( p_root == NULL )            i_ret = VLC_ENOMEM;        if( i_ret )        {            i_status = VLC_THREADS_ERROR;        }        else        {            i_initializations++;            i_status = VLC_THREADS_READY;        }    }    else    {        /* Just increment the initialization count */        i_initializations++;    }    /* If we have lazy mutex initialization support, unlock the mutex;     * otherwize, do a naive wait loop. */#if defined( PTH_INIT_IN_PTH_H )    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( HAVE_KERNEL_SCHEDULER_H )    while( i_status == VLC_THREADS_PENDING ) msleep( THREAD_SLEEP );#elif defined( PTHREAD_COND_T_IN_PTHREAD_H )    pthread_mutex_unlock( &once_mutex );#elif defined( HAVE_CTHREADS_H )    while( i_status == VLC_THREADS_PENDING ) msleep( THREAD_SLEEP );#endif    if( i_status != VLC_THREADS_READY )    {        return VLC_ETHREAD;    }    return i_ret;}/***************************************************************************** * vlc_threads_end: stop threads system ***************************************************************************** * FIXME: This function is far from being threadsafe. *****************************************************************************/int __vlc_threads_end( vlc_object_t *p_this ){#if defined( PTH_INIT_IN_PTH_H )#elif defined( ST_INIT_IN_ST_H )#elif defined( UNDER_CE )#elif defined( WIN32 )#elif defined( HAVE_KERNEL_SCHEDULER_H )#elif defined( PTHREAD_COND_T_IN_PTHREAD_H )    pthread_mutex_lock( &once_mutex );#elif defined( HAVE_CTHREADS_H )#endif    if( i_initializations == 0 )        return VLC_EGENERIC;    i_initializations--;    if( i_initializations == 0 )    {        i_status = VLC_THREADS_UNINITIALIZED;        vlc_object_destroy( p_root );    }#if defined( PTH_INIT_IN_PTH_H )    if( i_initializations == 0 )    {        return ( pth_kill() == FALSE );    }#elif defined( ST_INIT_IN_ST_H )#elif defined( UNDER_CE )#elif defined( WIN32 )#elif defined( HAVE_KERNEL_SCHEDULER_H )#elif defined( PTHREAD_COND_T_IN_PTHREAD_H )    pthread_mutex_unlock( &once_mutex );#elif defined( HAVE_CTHREADS_H )#endif    return VLC_SUCCESS;}/***************************************************************************** * vlc_mutex_init: initialize a mutex *****************************************************************************/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->mutex ) == FALSE );#elif defined( ST_INIT_IN_ST_H )    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( p_this->p_libvlc->SignalObjectAndWait &&        !p_this->p_libvlc->b_fast_mutex )    {        /* We are running on NT/2K/XP, we can use SignalObjectAndWait */        p_mutex->mutex = CreateMutex( 0, FALSE, 0 );        return ( p_mutex->mutex != NULL ? 0 : 1 );    }    else    {        p_mutex->mutex = NULL;        InitializeCriticalSection( &p_mutex->csection );        return 0;    }#elif defined( HAVE_KERNEL_SCHEDULER_H )    /* check the arguments and whether it's already been initialized */    if( p_mutex == NULL )    {        return B_BAD_VALUE;    }    if( p_mutex->init == 9999 )    {        return EALREADY;    }    p_mutex->lock = create_sem( 1, "BeMutex" );    if( p_mutex->lock < B_NO_ERROR )    {        return( -1 );    }    p_mutex->init = 9999;    return B_OK;#elif defined( PTHREAD_COND_T_IN_PTHREAD_H )#   if defined(DEBUG) && defined(SYS_LINUX)    {        /* 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->mutex, &attr );        pthread_mutexattr_destroy( &attr );        return( i_result );    }#   endif    return pthread_mutex_init( &p_mutex->mutex, NULL );#elif defined( HAVE_CTHREADS_H )    mutex_init( p_mutex );    return 0;#endif}/***************************************************************************** * vlc_mutex_destroy: destroy a mutex, inner version *****************************************************************************/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 )    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 )    {        CloseHandle( p_mutex->mutex );    }    else    {        DeleteCriticalSection( &p_mutex->csection );    }    return 0;#elif defined( HAVE_KERNEL_SCHEDULER_H )    if( p_mutex->init == 9999 )    {        delete_sem( p_mutex->lock );    }    p_mutex->init = 0;    return B_OK;#elif defined( PTHREAD_COND_T_IN_PTHREAD_H )    i_result = pthread_mutex_destroy( &p_mutex->mutex );    if ( i_result )    {        i_thread = (int)pthread_self();        psz_error = strerror(i_result);    }#elif defined( HAVE_CTHREADS_H )    return 0;#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;}/***************************************************************************** * vlc_cond_init: initialize a condition *****************************************************************************/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->cond ) == FALSE );#elif defined( ST_INIT_IN_ST_H )    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;    /* Misc init */    p_condvar->i_win9x_cv = p_this->p_libvlc->i_win9x_cv;    p_condvar->SignalObjectAndWait = p_this->p_libvlc->SignalObjectAndWait;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -