pth_cond_t cond;
vlc_object_t * p_this;
} vlc_cond_t;
+typedef struct
+{
+} vlc_threadvar_t;
#elif defined( ST_INIT_IN_ST_H )
typedef st_thread_t vlc_thread_t;
st_cond_t cond;
vlc_object_t * p_this;
} vlc_cond_t;
+typedef struct
+{
+} vlc_threadvar_t;
#elif defined( WIN32 ) || defined( UNDER_CE )
typedef HANDLE vlc_thread_t;
vlc_object_t * p_this;
} vlc_cond_t;
+typedef struct
+{
+ DWORD handle;
+} vlc_threadvar_t;
+
#elif defined( HAVE_KERNEL_SCHEDULER_H )
/* This is the BeOS implementation of the vlc threads, note that the mutex is
* not a real mutex and the cond_var is not like a pthread cond_var but it is
vlc_object_t * p_this;
} vlc_cond_t;
+typedef struct
+{
+} vlc_threadvar_t;
+
+
#elif defined( PTHREAD_COND_T_IN_PTHREAD_H )
typedef pthread_t vlc_thread_t;
typedef struct
vlc_object_t * p_this;
} vlc_cond_t;
+typedef struct
+{
+ pthread_key_t handle;
+} vlc_threadvar_t;
+
#elif defined( HAVE_CTHREADS_H )
typedef cthread_t vlc_thread_t;
vlc_object_t * p_this;
} vlc_cond_t;
+typedef struct
+{
+ cthread_key_t handle;
+} vlc_threadvar_t;
+
#endif
VLC_EXPORT( int, __vlc_mutex_destroy, ( const char *, int, vlc_mutex_t * ) );
VLC_EXPORT( int, __vlc_cond_init, ( vlc_object_t *, vlc_cond_t * ) );
VLC_EXPORT( int, __vlc_cond_destroy, ( const char *, int, vlc_cond_t * ) );
+VLC_EXPORT( int, __vlc_threadvar_create, (vlc_object_t *, vlc_threadvar_t * ) );
VLC_EXPORT( int, __vlc_thread_create, ( vlc_object_t *, const char *, int, const char *, void * ( * ) ( void * ), int, vlc_bool_t ) );
VLC_EXPORT( int, __vlc_thread_set_priority, ( vlc_object_t *, const char *, int, int ) );
VLC_EXPORT( void, __vlc_thread_ready, ( vlc_object_t * ) );
#define vlc_cond_destroy( P_COND ) \
__vlc_cond_destroy( __FILE__, __LINE__, P_COND )
+/*****************************************************************************
+ * vlc_threadvar_create: create a thread-local variable
+ *****************************************************************************/
+#define vlc_threadvar_create( PTHIS, P_TLS ) \
+ __vlc_threadvar_create( PTHIS, P_TLS )
+
+/*****************************************************************************
+ * vlc_threadvar_set: create: set the value of a thread-local variable
+ *****************************************************************************/
+#define vlc_threadvar_set( P_TLS , P_VAL ) \
+ __vlc_threadvar_set( __FILE__, __LINE__, P_TLS, P_VAL )
+
+static inline int __vlc_threadvar_set( char* psz_file, int line,
+ vlc_threadvar_t * p_tls, void *p_value )
+{
+ int i_ret;
+
+#if defined( PTH_INIT_IN_PTH_H ) || \
+ defined( ST_INIT_IN_ST_H ) || defined( HAVE_KERNEL_SCHEDULER_H )
+ return -1;
+
+#elif defined( UNDER_CE ) || defined( WIN32 )
+ i_ret = ( TlsSetValue( &p_tls->handle, p_value ) != 0 );
+
+#elif defined( PTHREAD_COND_T_IN_PTHREAD_H )
+ i_ret = pthread_setspecific( p_tls->handle, p_value );
+
+#elif defined( HAVE_CTHREADS_H )
+ i_ret = cthread_setspecific( p_tls->handle, p_value );
+#endif
+
+ return i_ret;
+}
+
+/*****************************************************************************
+ * vlc_threadvar_get: create: get the value of a thread-local variable
+ *****************************************************************************/
+#define vlc_threadvar_get( P_TLS ) \
+ __vlc_threadvar_get( __FILE__, __LINE__, P_TLS )
+
+static inline void* __vlc_threadvar_get( char* psz_file, int line,
+ vlc_threadvar_t * p_tls )
+{
+ void* p_ret;
+
+#if defined( PTH_INIT_IN_PTH_H ) || \
+ defined( ST_INIT_IN_ST_H ) || defined( HAVE_KERNEL_SCHEDULER_H )
+ return NULL;
+
+#elif defined( UNDER_CE ) || defined( WIN32 )
+ p_ret = TlsGetValue( &p_tls->handle );
+
+#elif defined( PTHREAD_COND_T_IN_PTHREAD_H )
+ p_ret = pthread_getspecific( p_tls->handle );
+
+#elif defined( HAVE_CTHREADS_H )
+ if ( !cthread_getspecific( p_tls->handle, &p_ret ) )
+ {
+ p_ret = NULL;
+ }
+#endif
+
+ return p_ret;
+}
+
/*****************************************************************************
* vlc_thread_create: create a thread
*****************************************************************************/
return i_result;
}
+/*****************************************************************************
+ * vlc_tls_create: create a thread-local variable
+ *****************************************************************************/
+int __vlc_threadvar_create( vlc_object_t *p_this, vlc_threadvar_t *p_tls )
+{
+#if defined( PTH_INIT_IN_PTH_H )
+#elif defined( HAVE_KERNEL_SCHEDULER_H )
+#elif defined( ST_INIT_IN_ST_H )
+ msg_Err( p_this, "TLS not implemented" );
+ return VLC_EGENERIC;
+
+#elif defined( UNDER_CE ) || defined( WIN32 )
+#elif defined( WIN32 )
+ p_tls->handle = TlsAlloc();
+ if( p_tls->handle == 0xFFFFFFFF )
+ {
+ return VLC_EGENERIC;
+ }
+
+ msg_Err( p_this, "TLS not implemented" );
+ return VLC_EGENERIC;
+
+#elif defined( PTHREAD_COND_T_IN_PTHREAD_H )
+ return pthread_key_create( &p_tls->handle, NULL );
+
+#elif defined( HAVE_CTHREADS_H )
+ return cthread_keycreate( &p_tls-handle );
+#endif
+}
+
/*****************************************************************************
* vlc_thread_create: create a thread, inner version
*****************************************************************************
import native_libvlc_test
class NativeLibvlcTestCase( unittest.TestCase ):
+ def testTls( self ):
+ """[Thread] Set TLS"""
+ native_libvlc_test.threadvar_test()
def test1Exception( self ):
"""[LibVLC] Checks libvlc_exception"""
# native_libvlc_test.exception_test()
DEF_METHOD( bsearch_direct_test, "Test Bsearch without structure" )
DEF_METHOD( bsearch_member_test, "Test Bsearch with structure" )
DEF_METHOD( dict_test, "Test dictionnaries" )
+ DEF_METHOD( threadvar_test, "Test TLS" )
{ NULL, NULL, 0, NULL }
};
PyObject *playlist_test( PyObject *self, PyObject *args );
PyObject *vlm_test( PyObject *self, PyObject *args );
+PyObject *threadvar_test( PyObject *self, PyObject *args );
+
/* Stats */
PyObject *timers_test( PyObject *self, PyObject *args );
--- /dev/null
+#include "../pyunit.h"
+#include <vlc/vlc.h>
+
+PyObject *threadvar_test( PyObject *self, PyObject *args )
+{
+ void *p_foo = malloc(1);
+ vlc_threadvar_t key, key2;
+
+ vlc_threadvar_create( NULL, &key );
+ vlc_threadvar_set( &key, p_foo );
+ ASSERT( vlc_threadvar_get( &key ) == p_foo, "key does not match" );
+
+ vlc_threadvar_create( NULL, &key2 );
+ vlc_threadvar_set( &key2, NULL );
+ ASSERT( vlc_threadvar_get( &key2 ) == NULL, "key2 does not match" );
+
+ Py_INCREF( Py_None );
+ return Py_None;
+}
native_libvlc_test = Extension( 'native_libvlc_test',
sources = ['native/init.c', 'native/url.c', 'native/i18n.c',
'native/stats.c', 'native/libvlc.c', 'native/profiles.c',
- 'native/algo.c'],
+ 'native/algo.c', 'native/threads.c'],
include_dirs = ['../include', '../', '/usr/win32/include' ],
extra_objects = [ '../src/.libs/libvlc.so', '../src/.libs/libvlc-control.so' ],
extra_compile_args = get_cflags(),