From 0ca3790ea7cd23e1134853a8818ab33ffb54baa2 Mon Sep 17 00:00:00 2001 From: =?utf8?q?R=C3=A9mi=20Denis-Courmont?= Date: Sun, 16 Sep 2007 10:39:50 +0000 Subject: [PATCH] Wrappers around thread signaling functions for object: - vlc_object_lock, vlc_object_unlock: take/release object_lock - vlc_object_signal: trigger object_wait - vlc_object_wait, vlc_object_timedwait: wait on object_wait --- include/vlc_objects.h | 47 +++++++++++++++++++--- src/misc/objects.c | 92 +++++++++++++++++++++++++++++++++++-------- 2 files changed, 116 insertions(+), 23 deletions(-) diff --git a/include/vlc_objects.h b/include/vlc_objects.h index 98267f7c39..03893fd33e 100644 --- a/include/vlc_objects.h +++ b/include/vlc_objects.h @@ -96,9 +96,6 @@ struct vlc_object_t *****************************************************************************/ VLC_EXPORT( void *, __vlc_object_create, ( vlc_object_t *, int ) ); VLC_EXPORT( void, __vlc_object_destroy, ( vlc_object_t * ) ); -VLC_EXPORT( void, __vlc_object_kill, ( vlc_object_t * ) ); -VLC_EXPORT( vlc_bool_t, __vlc_object_dying_unlocked, ( vlc_object_t * ) ); -VLC_EXPORT( vlc_bool_t, __vlc_object_dying, ( vlc_object_t * ) ); VLC_EXPORT( void, __vlc_object_attach, ( vlc_object_t *, vlc_object_t * ) ); VLC_EXPORT( void, __vlc_object_detach, ( vlc_object_t * ) ); VLC_EXPORT( void *, __vlc_object_get, ( vlc_object_t *, int ) ); @@ -118,9 +115,6 @@ VLC_EXPORT( void, vlc_list_release, ( vlc_list_t * ) ); __vlc_object_destroy( VLC_OBJECT(a) ); \ (a) = NULL; } while(0) -#define vlc_object_kill(a) \ - __vlc_object_kill( VLC_OBJECT(a) ) - #define vlc_object_detach(a) \ __vlc_object_detach( VLC_OBJECT(a) ) @@ -144,3 +138,44 @@ VLC_EXPORT( void, vlc_list_release, ( vlc_list_t * ) ); #define vlc_list_find(a,b,c) \ __vlc_list_find( VLC_OBJECT(a),b,c) + + +/* Objects and threading */ +VLC_EXPORT( void, __vlc_object_lock, ( vlc_object_t * ) ); +#define vlc_object_lock( obj ) \ + __vlc_object_lock( VLC_OBJECT( obj ) ) + +VLC_EXPORT( void, __vlc_object_unlock, ( vlc_object_t * ) ); +#define vlc_object_unlock( obj ) \ + __vlc_object_unlock( VLC_OBJECT( obj ) ) + +VLC_EXPORT( vlc_bool_t, __vlc_object_wait, ( vlc_object_t * ) ); +#define vlc_object_wait( obj ) \ + __vlc_object_wait( VLC_OBJECT( obj ) ) + +static inline +vlc_bool_t __vlc_object_lock_and_wait( vlc_object_t *obj ) +{ + vlc_bool_t b; + + vlc_object_lock( obj ); + b = vlc_object_wait( obj ); + vlc_object_unlock( obj ); + return b; +} + +VLC_EXPORT( int, __vlc_object_timedwait, ( vlc_object_t *, mtime_t ) ); +#define vlc_object_timedwait( obj, d ) \ + __vlc_object_timedwait( VLC_OBJECT( obj ), d ) + +VLC_EXPORT( void, __vlc_object_signal_unlocked, ( vlc_object_t * ) ); +#define vlc_object_signal_unlocked( obj ) \ + __vlc_object_signal_unlocked( VLC_OBJECT( obj ) ) + +VLC_EXPORT( void, __vlc_object_signal, ( vlc_object_t * ) ); +#define vlc_object_signal( obj ) \ + __vlc_object_signal( VLC_OBJECT( obj ) ) + +VLC_EXPORT( void, __vlc_object_kill, ( vlc_object_t * ) ); +#define vlc_object_kill(a) \ + __vlc_object_kill( VLC_OBJECT(a) ) diff --git a/src/misc/objects.c b/src/misc/objects.c index 0e26ff11dd..b1d27d0b3b 100644 --- a/src/misc/objects.c +++ b/src/misc/objects.c @@ -446,34 +446,92 @@ void __vlc_object_destroy( vlc_object_t *p_this ) } -void __vlc_object_kill( vlc_object_t *p_this ) +/** Inter-object signaling */ + +void __vlc_object_lock( vlc_object_t *obj ) { - vlc_mutex_lock( &p_this->object_lock ); + vlc_mutex_lock( &obj->object_lock ); +} - if( p_this->i_object_type == VLC_OBJECT_LIBVLC ) - for( int i = 0; i < p_this->i_children ; i++ ) - vlc_object_kill( p_this->pp_children[i] ); +void __vlc_object_unlock( vlc_object_t *obj ) +{ + vlc_assert_locked( &p_this->object_lock ); + vlc_mutex_unlock( &obj->object_lock ); +} - p_this->b_die = VLC_TRUE; - vlc_cond_signal( &p_this->object_wait ); - vlc_mutex_unlock( &p_this->object_lock ); +/** + * Waits for the object to be signaled (using vlc_object_signal()). + * If the object already has a signal pending, this function will return + * immediately. It is asserted that the caller holds the object lock. + * + * @return true if the object is dying and should terminate. + */ +vlc_bool_t __vlc_object_wait( vlc_object_t *obj ) +{ + vlc_assert_locked( &obj->object_lock ); + vlc_cond_wait( &obj->object_wait, &obj->object_lock ); + return obj->b_die; } -vlc_bool_t __vlc_object_dying_unlocked( vlc_object_t *p_this ) +/** + * Waits for the object to be signaled (using vlc_object_signal()), or for + * a timer to expire. + * If the object already has a signal pending, this function will return + * immediately. It is asserted that the caller holds the object lock. + * + * @return negative if the object is dying and should terminate, + * positive if the the object has been signaled but is not dying, + * 0 if timeout has been reached. + */ +int __vlc_object_timedwait( vlc_object_t *obj, mtime_t deadline ) { - vlc_assert_locked( &p_this->object_lock ); - return p_this->b_die; + int v; + + vlc_assert_locked( &obj->object_lock ); + v = vlc_cond_timedwait( &obj->object_wait, &obj->object_lock, deadline ); + if( v == 0 ) /* signaled */ + return obj->b_die ? -1 : 1; + return 0; +} + + +/** + * Signals an object for which the lock is held. + */ +void __vlc_object_signal_unlocked( vlc_object_t *obj ) +{ + vlc_assert_locked( &obj->object_lock ); + vlc_cond_signal( &obj->object_wait ); +} + + +/** + * Signals an object for which the lock is NOT held. + */ +void __vlc_object_signal( vlc_object_t *obj ) +{ + vlc_mutex_lock( &obj->object_lock ); + vlc_object_signal_unlocked( obj ); + vlc_mutex_unlock( &obj->object_lock ); } -vlc_bool_t __vlc_object_dying( vlc_object_t *p_this ) +/** + * Requests termination of an object. + * If the object is LibVLC, also request to terminate all its children. + */ +void __vlc_object_kill( vlc_object_t *p_this ) { - vlc_bool_t b; - vlc_mutex_lock( &p_this->object_lock ); - b = __vlc_object_dying_unlocked( p_this ); - vlc_mutex_unlock( &p_this->object_lock ); - return b; + vlc_mutex_lock( &p_this->object_lock ); + + if( p_this->i_object_type == VLC_OBJECT_LIBVLC ) + for( int i = 0; i < p_this->i_children ; i++ ) + vlc_object_kill( p_this->pp_children[i] ); + + p_this->b_die = VLC_TRUE; + vlc_object_signal_unlocked( p_this ); + vlc_mutex_unlock( &p_this->object_lock ); } -- 2.39.2