Changeset 234a17d087d4b5648adb9051a847db31bbc47149

Show
Ignore:
Timestamp:
30/05/08 17:18:02 (4 months ago)
Author:
Rémi Denis-Courmont <rem@videolan.org>
git-committer:
Rémi Denis-Courmont <rem@videolan.org> 1212160682 +0300
git-parent:

[7a826ae225a087ddeee5993e5230878dd2ded7c5]

git-author:
Rémi Denis-Courmont <rem@videolan.org> 1212160465 +0300
Message:

Improve the still really dumb reference checker

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • src/libvlc.h

    r523ef30 r234a17d  
    188188    unsigned         i_refcount; 
    189189    vlc_destructor_t pf_destructor; 
     190#ifndef NDEBUG 
     191    vlc_thread_t     creator_id; 
     192#endif 
    190193 
    191194    /* Objects tree structure */ 
  • src/misc/objects.c

    r85fa3c2 r234a17d  
    172172 
    173173    p_priv->next = VLC_OBJECT (p_libvlc_global); 
     174#if defined (NDEBUG) 
     175    /* ... */ 
     176#elif defined (LIBVLC_USE_PTRHEAD) 
     177    p_priv->creator_id = pthread_self (); 
     178#elif defined (WIN32) 
     179    p_priv->creator_id = GetCurrentThreadId (); 
     180#endif 
    174181    vlc_mutex_lock( &structure_lock ); 
    175182    p_priv->prev = vlc_internals (p_libvlc_global)->prev; 
     
    14821489 
    14831490#ifndef NDEBUG 
     1491# ifdef __GLIBC__ 
     1492#  include <execinfo.h> 
     1493# endif 
     1494 
    14841495void vlc_refcheck (vlc_object_t *obj) 
    14851496{ 
    14861497    static unsigned errors = 0; 
    1487     vlc_object_t *caller = vlc_threadobj (); 
    1488     vlc_object_internals_t *priv = vlc_internals (obj); 
    1489     int refs; 
    1490  
    14911498    if (errors > 100) 
    14921499        return; 
    14931500 
    1494     if (!caller) 
    1495         return; /* main thread, not sure how to handle it */ 
    1496  
    1497     /* An object can always access itself without reference! */ 
     1501    /* Anyone can use the root object (though it should not exist) */ 
     1502    if (obj == VLC_OBJECT (vlc_global ())) 
     1503        return; 
     1504 
     1505    /* Anyone can use its libvlc instance object */ 
     1506    if (obj == VLC_OBJECT (obj->p_libvlc)) 
     1507        return; 
     1508 
     1509    /* The thread that created the object holds the initial reference */ 
     1510    vlc_object_internals_t *priv = vlc_internals (obj); 
     1511#if defined (LIBVLC_USE_PTHREAD) 
     1512    if (pthread_equal (priv->creator_id, pthread_self ())) 
     1513#elif defined WIN32 
     1514    if (priv->creator_id == GetCurrentThreadId ()) 
     1515#else 
     1516    if (0) 
     1517#endif 
     1518        return; 
     1519 
     1520    /* A thread can use its own object without reference! */ 
     1521    vlc_object_t *caller = vlc_threadobj (); 
    14981522    if (caller == obj) 
    14991523        return; 
    15001524 
    15011525    /* The calling thread is younger than the object. 
    1502      * Access could be valid, we would need more accounting. */ 
    1503     if (caller->i_object_id > obj->i_object_id) 
     1526     * Access could be valid through cross-thread synchronization; 
     1527     * we would need better accounting. */ 
     1528    if (caller && (caller->i_object_id > obj->i_object_id)) 
    15041529        return; 
    15051530 
     1531    int refs; 
    15061532    vlc_spin_lock (&priv->ref_spin); 
    15071533    refs = priv->i_refcount; 
     
    15131539        return; 
    15141540 
    1515     /* The parent of an object normally holds the unique reference. 
    1516      * As not all objects are threads, it could also be an ancestor. */ 
    1517     vlc_mutex_lock (&structure_lock); 
    1518     for (vlc_object_t *cur = obj; cur != NULL; cur = cur->p_parent) 
    1519         if (cur == caller) 
    1520         { 
    1521             vlc_mutex_unlock (&structure_lock); 
    1522             return; 
    1523         } 
    1524     vlc_mutex_unlock (&structure_lock); 
    1525  
    1526 #if 1 
    1527     if (caller->i_object_type == VLC_OBJECT_PLAYLIST) 
    1528         return; /* Playlist is too clever, or hopelessly broken. */ 
     1541    fprintf (stderr, "The %s %s thread object is accessing...\n" 
     1542             "the %s %s object in a suspicous manner.\n", 
     1543             caller && caller->psz_object_name 
     1544                     ? caller->psz_object_name : "unnamed", 
     1545             caller ? caller->psz_object_type : "main", 
     1546             obj->psz_object_name ? obj->psz_object_name : "unnamed", 
     1547             obj->psz_object_type); 
     1548    fflush (stderr); 
     1549 
     1550#ifdef __GLIBC__ 
     1551    void *stack[20]; 
     1552    int stackdepth = backtrace (stack, sizeof (stack) / sizeof (stack[0])); 
     1553    backtrace_symbols_fd (stack, stackdepth, 2); 
    15291554#endif 
    1530     msg_Err (caller, "This thread is accessing..."); 
    1531     msg_Err (obj, "...this object in a suspicious manner."); 
    15321555 
    15331556    if (++errors == 100) 
    1534         msg_Err (caller, "Too many reference errors"); 
     1557        fprintf (stderr, "Too many reference errors!\n"); 
    15351558} 
    15361559#endif