Commit 71adf301 authored by Rémi Denis-Courmont's avatar Rémi Denis-Courmont

VLM: use custom reference count instead of object destructor

This should fix a crash whereby VLM is deleted before its child
VOD server object.
parent 17940740
...@@ -51,6 +51,7 @@ ...@@ -51,6 +51,7 @@
#if defined (WIN32) && !defined (UNDER_CE) #if defined (WIN32) && !defined (UNDER_CE)
#include <sys/timeb.h> /* ftime() */ #include <sys/timeb.h> /* ftime() */
#endif #endif
#include <limits.h>
#include <vlc_input.h> #include <vlc_input.h>
#include <vlc_stream.h> #include <vlc_stream.h>
...@@ -66,7 +67,6 @@ ...@@ -66,7 +67,6 @@
* Local prototypes. * Local prototypes.
*****************************************************************************/ *****************************************************************************/
static void vlm_Destructor( vlm_t *p_vlm );
static void* Manage( void * ); static void* Manage( void * );
static int vlm_MediaVodControl( void *, vod_media_t *, const char *, int, va_list ); static int vlm_MediaVodControl( void *, vod_media_t *, const char *, int, va_list );
...@@ -139,7 +139,10 @@ vlm_t *vlm_New ( vlc_object_t *p_this ) ...@@ -139,7 +139,10 @@ vlm_t *vlm_New ( vlc_object_t *p_this )
p_vlm = *pp_vlm; p_vlm = *pp_vlm;
if( p_vlm ) if( p_vlm )
{ /* VLM already exists */ { /* VLM already exists */
vlc_object_hold( p_vlm ); if( likely( p_vlm->users < UINT_MAX ) )
p_vlm->users++;
else
p_vlm = NULL;
vlc_mutex_unlock( &vlm_mutex ); vlc_mutex_unlock( &vlm_mutex );
return p_vlm; return p_vlm;
} }
...@@ -157,6 +160,7 @@ vlm_t *vlm_New ( vlc_object_t *p_this ) ...@@ -157,6 +160,7 @@ vlm_t *vlm_New ( vlc_object_t *p_this )
vlc_mutex_init( &p_vlm->lock ); vlc_mutex_init( &p_vlm->lock );
vlc_mutex_init( &p_vlm->lock_manage ); vlc_mutex_init( &p_vlm->lock_manage );
vlc_cond_init_daytime( &p_vlm->wait_manage ); vlc_cond_init_daytime( &p_vlm->wait_manage );
p_vlm->users = 1;
p_vlm->input_state_changed = false; p_vlm->input_state_changed = false;
p_vlm->i_id = 1; p_vlm->i_id = 1;
TAB_INIT( p_vlm->i_media, p_vlm->media ); TAB_INIT( p_vlm->i_media, p_vlm->media );
...@@ -196,7 +200,6 @@ vlm_t *vlm_New ( vlc_object_t *p_this ) ...@@ -196,7 +200,6 @@ vlm_t *vlm_New ( vlc_object_t *p_this )
} }
free( psz_vlmconf ); free( psz_vlmconf );
vlc_object_set_destructor( p_vlm, (vlc_destructor_t)vlm_Destructor );
vlc_mutex_unlock( &vlm_mutex ); vlc_mutex_unlock( &vlm_mutex );
return p_vlm; return p_vlm;
...@@ -208,18 +211,22 @@ vlm_t *vlm_New ( vlc_object_t *p_this ) ...@@ -208,18 +211,22 @@ vlm_t *vlm_New ( vlc_object_t *p_this )
void vlm_Delete( vlm_t *p_vlm ) void vlm_Delete( vlm_t *p_vlm )
{ {
/* vlm_Delete() is serialized against itself, and against vlm_New(). /* vlm_Delete() is serialized against itself, and against vlm_New().
* This way, vlm_Destructor () (called from vlc_objet_release() above) * This mutex protects libvlc_priv->p_vlm and p_vlm->users. */
* is serialized against setting libvlc_priv->p_vlm from vlm_New(). */
vlc_mutex_lock( &vlm_mutex ); vlc_mutex_lock( &vlm_mutex );
vlc_object_release( p_vlm ); assert( p_vlm->users > 0 );
if( --p_vlm->users == 0 )
{
assert( libvlc_priv(p_vlm->p_libvlc)->p_vlm = p_vlm );
libvlc_priv(p_vlm->p_libvlc)->p_vlm = NULL;
}
else
p_vlm = NULL;
vlc_mutex_unlock( &vlm_mutex ); vlc_mutex_unlock( &vlm_mutex );
}
/***************************************************************************** if( p_vlm == NULL )
* vlm_Destructor: return;
*****************************************************************************/
static void vlm_Destructor( vlm_t *p_vlm ) /* Destroy and release VLM */
{
vlc_mutex_lock( &p_vlm->lock ); vlc_mutex_lock( &p_vlm->lock );
vlm_ControlInternal( p_vlm, VLM_CLEAR_MEDIAS ); vlm_ControlInternal( p_vlm, VLM_CLEAR_MEDIAS );
TAB_CLEAN( p_vlm->i_media, p_vlm->media ); TAB_CLEAN( p_vlm->i_media, p_vlm->media );
...@@ -228,7 +235,6 @@ static void vlm_Destructor( vlm_t *p_vlm ) ...@@ -228,7 +235,6 @@ static void vlm_Destructor( vlm_t *p_vlm )
TAB_CLEAN( p_vlm->i_schedule, p_vlm->schedule ); TAB_CLEAN( p_vlm->i_schedule, p_vlm->schedule );
vlc_mutex_unlock( &p_vlm->lock ); vlc_mutex_unlock( &p_vlm->lock );
libvlc_priv(p_vlm->p_libvlc)->p_vlm = NULL;
vlc_object_kill( p_vlm ); vlc_object_kill( p_vlm );
if( p_vlm->p_vod ) if( p_vlm->p_vod )
...@@ -248,6 +254,7 @@ static void vlm_Destructor( vlm_t *p_vlm ) ...@@ -248,6 +254,7 @@ static void vlm_Destructor( vlm_t *p_vlm )
vlc_cond_destroy( &p_vlm->wait_manage ); vlc_cond_destroy( &p_vlm->wait_manage );
vlc_mutex_destroy( &p_vlm->lock ); vlc_mutex_destroy( &p_vlm->lock );
vlc_mutex_destroy( &p_vlm->lock_manage ); vlc_mutex_destroy( &p_vlm->lock_manage );
vlc_object_release( p_vlm );
} }
/***************************************************************************** /*****************************************************************************
......
...@@ -89,6 +89,8 @@ struct vlm_t ...@@ -89,6 +89,8 @@ struct vlm_t
vlc_thread_t thread; vlc_thread_t thread;
vlc_mutex_t lock_manage; vlc_mutex_t lock_manage;
vlc_cond_t wait_manage; vlc_cond_t wait_manage;
unsigned users;
/* tell vlm thread there is work to do */ /* tell vlm thread there is work to do */
bool input_state_changed; bool input_state_changed;
/* */ /* */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment