[vlc-devel] commit: One child is one reference ( Rémi Denis-Courmont )
git version control
git at videolan.org
Sat Sep 20 20:17:07 CEST 2008
vlc | branch: master | Rémi Denis-Courmont <rdenis at simphalempin.com> | Sat Sep 20 18:48:33 2008 +0300| [559c876b10bf4391dc592cc5d21ae99124a4d5ec] | committer: Rémi Denis-Courmont
One child is one reference
Avoid objects being detached asynchronously too early.
Side effect is that you cannot free your children in the destructor
(that would be a reference loop).
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=559c876b10bf4391dc592cc5d21ae99124a4d5ec
---
src/misc/objects.c | 29 +++++++++++++++++------------
1 files changed, 17 insertions(+), 12 deletions(-)
diff --git a/src/misc/objects.c b/src/misc/objects.c
index d4f3247..f89133e 100644
--- a/src/misc/objects.c
+++ b/src/misc/objects.c
@@ -633,6 +633,7 @@ void * __vlc_object_yield( vlc_object_t *p_this )
void __vlc_object_release( vlc_object_t *p_this )
{
vlc_object_internals_t *internals = vlc_internals( p_this );
+ vlc_object_t *parent = NULL;
bool b_should_destroy;
vlc_spin_lock( &internals->ref_spin );
@@ -659,6 +660,10 @@ void __vlc_object_release( vlc_object_t *p_this )
if( b_should_destroy )
{
+ /* We have no children */
+ assert (internals->i_children == 0);
+ parent = p_this->p_parent;
+
#ifndef NDEBUG
if( VLC_OBJECT(p_this->p_libvlc) == p_this )
{
@@ -687,25 +692,21 @@ void __vlc_object_release( vlc_object_t *p_this )
vlc_internals (internals->next)->prev = internals->prev;
vlc_internals (internals->prev)->next = internals->next;
- /* Detach from parent to protect against FIND_CHILDREN */
- vlc_object_detach_unlocked (p_this);
- /* Detach from children to protect against FIND_PARENT */
- for (int i = 0; i < internals->i_children; i++)
- internals->pp_children[i]->p_parent = NULL;
+ if (parent)
+ /* Detach from parent to protect against FIND_CHILDREN */
+ vlc_object_detach_unlocked (p_this);
}
-
vlc_mutex_unlock( &structure_lock );
if( b_should_destroy )
{
int canc;
- free( internals->pp_children );
- internals->pp_children = NULL;
- internals->i_children = 0;
canc = vlc_savecancel ();
vlc_object_destroy( p_this );
vlc_restorecancel (canc);
+ if (parent)
+ vlc_object_release (parent);
}
}
@@ -720,6 +721,7 @@ void __vlc_object_attach( vlc_object_t *p_this, vlc_object_t *p_parent )
{
if( !p_this ) return;
+ vlc_object_yield (p_parent);
vlc_mutex_lock( &structure_lock );
/* Attach the parent to its child */
@@ -785,14 +787,17 @@ static void vlc_object_detach_unlocked (vlc_object_t *p_this)
*****************************************************************************/
void __vlc_object_detach( vlc_object_t *p_this )
{
+ vlc_object_t *p_parent;
if( !p_this ) return;
vlc_mutex_lock( &structure_lock );
- if( !p_this->p_parent )
- msg_Err( p_this, "object is not attached" );
- else
+ p_parent = p_this->p_parent;
+ if (p_parent)
vlc_object_detach_unlocked( p_this );
vlc_mutex_unlock( &structure_lock );
+
+ if (p_parent)
+ vlc_object_release (p_parent);
}
More information about the vlc-devel
mailing list