[vlc-commits] VLM: use custom reference count instead of object destructor
Rémi Denis-Courmont
git at videolan.org
Tue Jul 5 17:10:04 CEST 2011
vlc | branch: master | Rémi Denis-Courmont <remi at remlab.net> | Tue Jul 5 18:09:04 2011 +0300| [71adf301e50aef185ef903d542896071f78323ff] | committer: 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.
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=71adf301e50aef185ef903d542896071f78323ff
---
src/input/vlm.c | 33 ++++++++++++++++++++-------------
src/input/vlm_internal.h | 2 ++
2 files changed, 22 insertions(+), 13 deletions(-)
diff --git a/src/input/vlm.c b/src/input/vlm.c
index 66dfbf7..ee7539d 100644
--- a/src/input/vlm.c
+++ b/src/input/vlm.c
@@ -51,6 +51,7 @@
#if defined (WIN32) && !defined (UNDER_CE)
#include <sys/timeb.h> /* ftime() */
#endif
+#include <limits.h>
#include <vlc_input.h>
#include <vlc_stream.h>
@@ -66,7 +67,6 @@
* Local prototypes.
*****************************************************************************/
-static void vlm_Destructor( vlm_t *p_vlm );
static void* Manage( void * );
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 )
p_vlm = *pp_vlm;
if( p_vlm )
{ /* 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 );
return p_vlm;
}
@@ -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_manage );
vlc_cond_init_daytime( &p_vlm->wait_manage );
+ p_vlm->users = 1;
p_vlm->input_state_changed = false;
p_vlm->i_id = 1;
TAB_INIT( p_vlm->i_media, p_vlm->media );
@@ -196,7 +200,6 @@ vlm_t *vlm_New ( vlc_object_t *p_this )
}
free( psz_vlmconf );
- vlc_object_set_destructor( p_vlm, (vlc_destructor_t)vlm_Destructor );
vlc_mutex_unlock( &vlm_mutex );
return p_vlm;
@@ -208,18 +211,22 @@ vlm_t *vlm_New ( vlc_object_t *p_this )
void vlm_Delete( vlm_t *p_vlm )
{
/* vlm_Delete() is serialized against itself, and against vlm_New().
- * This way, vlm_Destructor () (called from vlc_objet_release() above)
- * is serialized against setting libvlc_priv->p_vlm from vlm_New(). */
+ * This mutex protects libvlc_priv->p_vlm and p_vlm->users. */
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 );
-}
-/*****************************************************************************
- * vlm_Destructor:
- *****************************************************************************/
-static void vlm_Destructor( vlm_t *p_vlm )
-{
+ if( p_vlm == NULL )
+ return;
+
+ /* Destroy and release VLM */
vlc_mutex_lock( &p_vlm->lock );
vlm_ControlInternal( p_vlm, VLM_CLEAR_MEDIAS );
TAB_CLEAN( p_vlm->i_media, p_vlm->media );
@@ -228,7 +235,6 @@ static void vlm_Destructor( vlm_t *p_vlm )
TAB_CLEAN( p_vlm->i_schedule, p_vlm->schedule );
vlc_mutex_unlock( &p_vlm->lock );
- libvlc_priv(p_vlm->p_libvlc)->p_vlm = NULL;
vlc_object_kill( p_vlm );
if( p_vlm->p_vod )
@@ -248,6 +254,7 @@ static void vlm_Destructor( vlm_t *p_vlm )
vlc_cond_destroy( &p_vlm->wait_manage );
vlc_mutex_destroy( &p_vlm->lock );
vlc_mutex_destroy( &p_vlm->lock_manage );
+ vlc_object_release( p_vlm );
}
/*****************************************************************************
diff --git a/src/input/vlm_internal.h b/src/input/vlm_internal.h
index 0ecfd37..875d50c 100644
--- a/src/input/vlm_internal.h
+++ b/src/input/vlm_internal.h
@@ -89,6 +89,8 @@ struct vlm_t
vlc_thread_t thread;
vlc_mutex_t lock_manage;
vlc_cond_t wait_manage;
+ unsigned users;
+
/* tell vlm thread there is work to do */
bool input_state_changed;
/* */
More information about the vlc-commits
mailing list