⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 objects.c

📁 VLC Player Source Code
💻 C
📖 第 1 页 / 共 4 页
字号:
{    vlc_mutex_lock( &(vlc_internals(obj)->lock) );}void __vlc_object_unlock( vlc_object_t *obj ){    vlc_assert_locked( &(vlc_internals(obj)->lock) );    vlc_mutex_unlock( &(vlc_internals(obj)->lock) );}#ifdef WIN32# include <winsock2.h># include <ws2tcpip.h>/** * select()-able pipes emulated using Winsock */static int pipe (int fd[2]){    SOCKADDR_IN addr;    int addrlen = sizeof (addr);    SOCKET l = socket (PF_INET, SOCK_STREAM, IPPROTO_TCP), a,           c = socket (PF_INET, SOCK_STREAM, IPPROTO_TCP);    if ((l == INVALID_SOCKET) || (c == INVALID_SOCKET))        goto error;    memset (&addr, 0, sizeof (addr));    addr.sin_family = AF_INET;    addr.sin_addr.s_addr = htonl (INADDR_LOOPBACK);    if (bind (l, (PSOCKADDR)&addr, sizeof (addr))     || getsockname (l, (PSOCKADDR)&addr, &addrlen)     || listen (l, 1)     || connect (c, (PSOCKADDR)&addr, addrlen))        goto error;    a = accept (l, NULL, NULL);    if (a == INVALID_SOCKET)        goto error;    closesocket (l);    //shutdown (a, 0);    //shutdown (c, 1);    fd[0] = c;    fd[1] = a;    return 0;error:    if (l != INVALID_SOCKET)        closesocket (l);    if (c != INVALID_SOCKET)        closesocket (c);    return -1;}#undef  read#define read( a, b, c )  recv (a, b, c, 0)#undef  write#define write( a, b, c ) send (a, b, c, 0)#undef  close#define close( a )       closesocket (a)#endif /* WIN32 *//** * Returns the readable end of a pipe that becomes readable once termination * of the object is requested (vlc_object_kill()). * This can be used to wake-up out of a select() or poll() event loop, such * typically when doing network I/O. * * Note that the pipe will remain the same for the lifetime of the object. * DO NOT read the pipe nor close it yourself. Ever. * * @param obj object that would be "killed" * @return a readable pipe descriptor, or -1 on error. */int __vlc_object_waitpipe( vlc_object_t *obj ){    int pfd[2] = { -1, -1 };    vlc_object_internals_t *internals = vlc_internals( obj );    bool killed = false;    vlc_spin_lock (&internals->spin);    if (internals->pipes[0] == -1)    {        /* This can only ever happen if someone killed us without locking: */        assert (internals->pipes[1] == -1);        vlc_spin_unlock (&internals->spin);        if (pipe (pfd))            return -1;        vlc_spin_lock (&internals->spin);        if (internals->pipes[0] == -1)        {            internals->pipes[0] = pfd[0];            internals->pipes[1] = pfd[1];            pfd[0] = pfd[1] = -1;        }        killed = obj->b_die;    }    vlc_spin_unlock (&internals->spin);    if (killed)    {        /* Race condition: vlc_object_kill() already invoked! */        int fd;        vlc_spin_lock (&internals->spin);        fd = internals->pipes[1];        internals->pipes[1] = -1;        vlc_spin_unlock (&internals->spin);        msg_Dbg (obj, "waitpipe: object already dying");        if (fd != -1)            close (fd);    }    /* Race condition: two threads call pipe() - unlikely */    if (pfd[0] != -1)        close (pfd[0]);    if (pfd[1] != -1)        close (pfd[1]);    return internals->pipes[0];}/** * Waits for the object to be signaled (using vlc_object_signal()). * It is assumed that the caller has locked the object. This function will * unlock the object, and lock it again before returning. * If the object was signaled before the caller locked the object, it is * undefined whether the signal will be lost or will wake the process. * * @return true if the object is dying and should terminate. */void __vlc_object_wait( vlc_object_t *obj ){    vlc_object_internals_t *priv = vlc_internals( obj );    vlc_assert_locked( &priv->lock);    vlc_cond_wait( &priv->wait, &priv->lock );}/** * Waits for the object to be signaled (using vlc_object_signal()), or for * a timer to expire. It is asserted that the caller holds the object lock. * * @return 0 if the object was signaled before the timer expiration, or * ETIMEDOUT if the timer expired without any signal. */int __vlc_object_timedwait( vlc_object_t *obj, mtime_t deadline ){    vlc_object_internals_t *priv = vlc_internals( obj );    vlc_assert_locked( &priv->lock);    return vlc_cond_timedwait( &priv->wait, &priv->lock, deadline );}/** * Signals an object for which the lock is held. * At least one thread currently sleeping in vlc_object_wait() or * vlc_object_timedwait() will wake up, assuming that there is at least one * such thread in the first place. Otherwise, it is undefined whether the * signal will be lost or will wake up one or more thread later. */void __vlc_object_signal_unlocked( vlc_object_t *obj ){    vlc_assert_locked (&(vlc_internals(obj)->lock));    vlc_cond_signal( &(vlc_internals(obj)->wait) );}/** * 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_object_internals_t *priv = vlc_internals( p_this );    int fd;    vlc_object_lock( p_this );    p_this->b_die = true;    vlc_spin_lock (&priv->spin);    fd = priv->pipes[1];    priv->pipes[1] = -1;    vlc_spin_unlock (&priv->spin);    if( fd != -1 )    {        msg_Dbg (p_this, "waitpipe: object killed");        close (fd);    }    vlc_object_signal_unlocked( p_this );    /* This also serves as a memory barrier toward vlc_object_alive(): */    vlc_object_unlock( p_this );}/** * Find an object given its ID. * * This function looks for the object whose i_object_id field is i_id. * This function is slow, and often used to hide bugs. Do not use it. * If you need to retain reference to an object, yield the object pointer with * vlc_object_yield(), use the pointer as your reference, and call * vlc_object_release() when you're done. */void * vlc_object_get( int i_id ){    libvlc_global_data_t *p_libvlc_global = vlc_global();    vlc_object_t *obj = NULL;#ifndef NDEBUG    vlc_object_t *caller = vlc_threadobj ();    if (caller)        msg_Dbg (caller, "uses deprecated vlc_object_get(%d)", i_id);    else        fprintf (stderr, "main thread uses deprecated vlc_object_get(%d)\n",                 i_id);#endif    vlc_mutex_lock( &structure_lock );    for( obj = vlc_internals (p_libvlc_global)->next;         obj != VLC_OBJECT (p_libvlc_global);         obj = vlc_internals (obj)->next )    {        if( obj->i_object_id == i_id )        {            vlc_object_yield( obj );            goto out;        }    }    obj = NULL;#ifndef NDEBUG    if (caller)        msg_Warn (caller, "wants non-existing object %d", i_id);    else        fprintf (stderr, "main thread wants non-existing object %d\n", i_id);#endifout:    vlc_mutex_unlock( &structure_lock );    return obj;}/** **************************************************************************** * find a typed object and increment its refcount ***************************************************************************** * This function recursively looks for a given object type. i_mode can be one * of FIND_PARENT, FIND_CHILD or FIND_ANYWHERE. *****************************************************************************/void * __vlc_object_find( vlc_object_t *p_this, int i_type, int i_mode ){    vlc_object_t *p_found;    /* If we are of the requested type ourselves, don't look further */    if( !(i_mode & FIND_STRICT) && p_this->i_object_type == i_type )    {        vlc_object_yield( p_this );        return p_this;    }    /* Otherwise, recursively look for the object */    if ((i_mode & 0x000f) == FIND_ANYWHERE)    {#ifndef NDEBUG        if (i_type == VLC_OBJECT_PLAYLIST)	    msg_Err (p_this, "using vlc_object_find(VLC_OBJECT_PLAYLIST) "                     "instead of pl_Yield()");#endif        return vlc_object_find (p_this->p_libvlc, i_type,                                (i_mode & ~0x000f)|FIND_CHILD);    }    vlc_mutex_lock( &structure_lock );    p_found = FindObject( p_this, i_type, i_mode );    vlc_mutex_unlock( &structure_lock );    return p_found;}/** **************************************************************************** * find a named object and increment its refcount ***************************************************************************** * This function recursively looks for a given object name. i_mode can be one * of FIND_PARENT, FIND_CHILD or FIND_ANYWHERE. *****************************************************************************/void * __vlc_object_find_name( vlc_object_t *p_this, const char *psz_name,                               int i_mode ){    vlc_object_t *p_found;    /* If have the requested name ourselves, don't look further */    if( !(i_mode & FIND_STRICT)        && p_this->psz_object_name        && !strcmp( p_this->psz_object_name, psz_name ) )    {        vlc_object_yield( p_this );        return p_this;    }    vlc_mutex_lock( &structure_lock );    /* Otherwise, recursively look for the object */    if( (i_mode & 0x000f) == FIND_ANYWHERE )    {        vlc_object_t *p_root = p_this;        /* Find the root */        while( p_root->p_parent != NULL &&               p_root != VLC_OBJECT( p_this->p_libvlc ) )        {            p_root = p_root->p_parent;        }        p_found = FindObjectName( p_root, psz_name,                                 (i_mode & ~0x000f)|FIND_CHILD );        if( p_found == NULL && p_root != VLC_OBJECT( p_this->p_libvlc ) )        {            p_found = FindObjectName( VLC_OBJECT( p_this->p_libvlc ),                                      psz_name, (i_mode & ~0x000f)|FIND_CHILD );        }    }    else    {        p_found = FindObjectName( p_this, psz_name, i_mode );    }    vlc_mutex_unlock( &structure_lock );    return p_found;}/** * Increment an object reference counter. */void __vlc_object_yield( vlc_object_t *p_this ){    vlc_object_internals_t *internals = vlc_internals( p_this );    vlc_spin_lock( &internals->ref_spin );    /* Avoid obvious freed object uses */    assert( internals->i_refcount > 0 );    /* Increment the counter */    internals->i_refcount++;    vlc_spin_unlock( &internals->ref_spin );#ifdef LIBVLC_REFCHECK    /* Update the list of referenced objects */    /* Using TLS, so no need to lock */    /* The following line may leak memory if a thread leaks objects. */    held_list_t *newhead = malloc (sizeof (*newhead));    held_list_t *oldhead = vlc_threadvar_get (&held_objects);    newhead->next = oldhead;    newhead->obj = p_this;    vlc_threadvar_set (&held_objects, newhead);#endif}/***************************************************************************** * decrement an object refcount * And destroy the object if its refcount reach zero. *****************************************************************************/void __vlc_object_release( vlc_object_t *p_this ){    vlc_object_internals_t *internals = vlc_internals( p_this );    bool b_should_destroy;#ifdef LIBVLC_REFCHECK    /* Update the list of referenced objects */    /* Using TLS, so no need to lock */    for (held_list_t *hlcur = vlc_threadvar_get (&held_objects),                     *hlprev = NULL;         hlcur != NULL;         hlprev = hlcur, hlcur = hlcur->next)    {        if (hlcur->obj == p_this)        {            if (hlprev == NULL)                vlc_threadvar_set (&held_objects, hlcur->next);            else                hlprev->next = hlcur->next;            free (hlcur);            break;        }    }    /* TODO: what if releasing without references? */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -