X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=src%2Fmisc%2Fobjects.c;h=65802c77c74cb3d89bc5e3e96acfaf90ac5149c1;hb=12ade3e3bc975d5426ba4af155b7372c31093b31;hp=f8b6044587320fa8585403f6180f0324e396091a;hpb=c01dd91cd2d526332229ecea8d4f007c065026ea;p=vlc diff --git a/src/misc/objects.c b/src/misc/objects.c index f8b6044587..65802c77c7 100644 --- a/src/misc/objects.c +++ b/src/misc/objects.c @@ -67,6 +67,10 @@ #if defined (HAVE_SYS_EVENTFD_H) # include +# ifndef EFD_CLOEXEC +# define EFD_CLOEXEC 0 +# warning EFD_CLOEXEC missing. Consider updating libc. +# endif #endif @@ -86,7 +90,6 @@ static void DumpStructure( vlc_object_internals_t *, unsigned, char * ); static vlc_list_t * NewList ( int ); static void vlc_object_destroy( vlc_object_t *p_this ); -static void vlc_object_detach_unlocked (vlc_object_t *p_this); /***************************************************************************** * Local structure lock @@ -155,9 +158,6 @@ void *vlc_custom_create( vlc_object_t *p_this, size_t i_size, p_priv->b_thread = false; p_new->p_parent = NULL; p_priv->first = NULL; -#ifndef NDEBUG - p_priv->old_parent = NULL; -#endif /* Initialize mutexes and condvars */ vlc_mutex_init( &p_priv->var_lock ); @@ -254,9 +254,6 @@ static void vlc_object_destroy( vlc_object_t *p_this ) { vlc_object_internals_t *p_priv = vlc_internals( p_this ); - /* Objects are always detached beforehand */ - assert( !p_this->p_parent ); - /* Send a kill to the object's thread if applicable */ vlc_object_kill( p_this ); @@ -356,6 +353,9 @@ int vlc_object_waitpipe( vlc_object_t *obj ) /* This can only ever happen if someone killed us without locking: */ assert (internals->pipes[1] == -1); + /* pipe() is not a cancellation point, but write() is and eventfd() is + * unspecified (not in POSIX). */ + int canc = vlc_savecancel (); #if defined (HAVE_SYS_EVENTFD_H) internals->pipes[0] = internals->pipes[1] = eventfd (0, EFD_CLOEXEC); if (internals->pipes[0] == -1) @@ -370,6 +370,7 @@ int vlc_object_waitpipe( vlc_object_t *obj ) msg_Dbg (obj, "waitpipe: object already dying"); write (internals->pipes[1], &(uint64_t){ 1 }, sizeof (uint64_t)); } + vlc_restorecancel (canc); } vlc_mutex_unlock (&pipe_lock); return internals->pipes[0]; @@ -579,10 +580,18 @@ void vlc_object_release( vlc_object_t *p_this ) if( b_should_destroy ) { + /* Detach from parent to protect against FIND_CHILDREN */ parent = p_this->p_parent; - if (parent) - /* Detach from parent to protect against FIND_CHILDREN */ - vlc_object_detach_unlocked (p_this); + if (likely(parent)) + { + /* Unlink */ + if (internals->prev != NULL) + internals->prev->next = internals->next; + else + vlc_internals(parent)->first = internals->next; + if (internals->next != NULL) + internals->next->prev = internals->prev; + } /* We have no children */ assert (internals->first == NULL); @@ -607,7 +616,7 @@ void vlc_object_release( vlc_object_t *p_this ) * attach object to a parent object ***************************************************************************** * This function sets p_this as a child of p_parent, and p_parent as a parent - * of p_this. This link can be undone using vlc_object_detach. + * of p_this. *****************************************************************************/ void vlc_object_attach( vlc_object_t *p_this, vlc_object_t *p_parent ) { @@ -615,31 +624,13 @@ void vlc_object_attach( vlc_object_t *p_this, vlc_object_t *p_parent ) vlc_object_internals_t *pap = vlc_internals (p_parent); vlc_object_internals_t *priv = vlc_internals (p_this); - vlc_object_t *p_old_parent; priv->prev = NULL; vlc_object_hold (p_parent); libvlc_lock (p_this->p_libvlc); -#ifndef NDEBUG - /* Reparenting an object carries a risk of invalid access to the parent, - * from another thread. This can happen when inheriting a variable, or - * through any direct access to vlc_object_t.p_parent. Also, reparenting - * brings a functional bug, whereby the reparented object uses incorrect - * old values for inherited variables (as the new parent may have different - * variable values, especially if it is an input). - * Note that the old parent may be already destroyed. - * So its pointer must not be dereferenced. - */ - if (priv->old_parent) - msg_Info (p_this, "Reparenting an object is dangerous (%p -> %p)!", - priv->old_parent, p_parent); -#endif - - p_old_parent = p_this->p_parent; - if (p_old_parent) - vlc_object_detach_unlocked (p_this); /* Attach the parent to its child */ + assert (p_this->p_parent == NULL); p_this->p_parent = p_parent; /* Attach the child to its parent */ @@ -648,55 +639,8 @@ void vlc_object_attach( vlc_object_t *p_this, vlc_object_t *p_parent ) priv->next->prev = priv; pap->first = priv; libvlc_unlock (p_this->p_libvlc); - - if (p_old_parent) - vlc_object_release (p_old_parent); -} - - -static void vlc_object_detach_unlocked (vlc_object_t *p_this) -{ - assert (p_this->p_parent != NULL); - - vlc_object_internals_t *pap = vlc_internals (p_this->p_parent); - vlc_object_internals_t *priv = vlc_internals (p_this); - - /* Unlink */ - if (priv->prev != NULL) - priv->prev->next = priv->next; - else - pap->first = priv->next; - if (priv->next != NULL) - priv->next->prev = priv->prev; - - /* Remove p_this's parent */ -#ifndef NDEBUG - priv->old_parent = p_this->p_parent; -#endif - p_this->p_parent = NULL; } -#undef vlc_object_detach -/** - **************************************************************************** - * detach object from its parent - ***************************************************************************** - * This function removes all links between an object and its parent. - *****************************************************************************/ -void vlc_object_detach( vlc_object_t *p_this ) -{ - vlc_object_t *p_parent; - if( !p_this ) return; - - libvlc_lock (p_this->p_libvlc); - p_parent = p_this->p_parent; - if (p_parent) - vlc_object_detach_unlocked( p_this ); - libvlc_unlock (p_this->p_libvlc); - - if (p_parent) - vlc_object_release (p_parent); -} #undef vlc_list_children /** @@ -754,7 +698,6 @@ static void DumpVariable (const void *data, const VISIT which, const int depth) MYCASE( COORDS, "coords" ); MYCASE( ADDRESS, "address" ); MYCASE( MUTEX, "mutex" ); - MYCASE( LIST, "list" ); #undef MYCASE } printf( " *-o \"%s\" (%s", p_var->psz_name, psz_type ); @@ -776,7 +719,7 @@ static void DumpVariable (const void *data, const VISIT which, const int depth) printf( ": %s", p_var->val.b_bool ? "true" : "false" ); break; case VLC_VAR_INTEGER: - printf( ": %d", p_var->val.i_int ); + printf( ": %"PRId64, p_var->val.i_int ); break; case VLC_VAR_STRING: printf( ": \"%s\"", p_var->val.psz_string ); @@ -794,9 +737,6 @@ static void DumpVariable (const void *data, const VISIT which, const int depth) case VLC_VAR_ADDRESS: printf( ": %p", p_var->val.p_address ); break; - case VLC_VAR_LIST: - fputs( ": TODO", stdout ); - break; } fputc( '\n', stdout ); }