fix editpanel wdw lock issues, use undo bracketing to avoid stop playback deadlocks
[goodguy/cinelerra.git] / cinelerra-5.1 / guicast / bctrace.C
index 930eabfc50f6bf562969812b3810c664e6782c75..7e453925487b01931c480a541f23f91541b44134 100644 (file)
@@ -98,8 +98,9 @@ void BC_Trace::disable_locks()
        trace_locks = 0;
        while( lock_table.last ) {
                lock_item *p = (lock_item*)lock_table.last;
+               lock_table.remove_pointer(p);
                p->info->trace = 0;
-               lock_table.remove_pointer(p);  lock_free.append(p);
+               lock_free.append(p);
        }
        lock_free.clear();
        lock_table.unlock();
@@ -170,9 +171,15 @@ void BC_Trace::unset_lock2(int table_id, trace_info *info)
                p = (lock_item*)lock_table.last;
                while( p && p->id != table_id ) p = (lock_item*)p->previous;
        }
-       else
-               info->trace = 0;
-       if( p ) { lock_table.remove_pointer(p);  lock_free.append(p); }
+       if( p ) {
+               if( p->list == &lock_table ) {
+                       lock_table.remove_pointer(p);
+                       info->trace = 0;
+                       lock_free.append(p);
+               }
+               else
+                       printf("unset_lock2: free lock_item in lock_table %p\n", p);
+       }
        lock_table.unlock();
 }
 
@@ -185,9 +192,16 @@ void BC_Trace::unset_lock(trace_info *info)
                p = (lock_item*)lock_table.last;
                while( p && ( p->info!=info || !p->is_owner ) ) p = (lock_item*)p->previous;
        }
-       else
-               info->trace = 0;
-       if( p ) { lock_table.remove_pointer(p);  lock_free.append(p); }
+       info->trace = 0;
+       if( p ) {
+               if( p->list == &lock_table ) {
+                       lock_table.remove_pointer(p);
+                       info->trace = 0;
+                       lock_free.append(p);
+               }
+               else
+                       printf("unset_lock: free lock_item in lock_table %p\n", p);
+       }
        lock_table.unlock();
 }
 
@@ -196,11 +210,13 @@ void BC_Trace::unset_all_locks(trace_info *info)
 {
        if( !global_trace || !trace_locks ) return;
        lock_table.lock();
+       info->trace = 0;
        lock_item *p = (lock_item*)lock_table.first;
        while( p ) {
                lock_item *lp = p;  p = (lock_item*)p->next;
                if( lp->info != info ) continue;
-               lock_table.remove_pointer(lp);  lock_free.append(lp);
+               lock_table.remove_pointer(lp);
+               lock_free.append(lp);
        }
        lock_table.unlock();
 }
@@ -213,7 +229,9 @@ void BC_Trace::clear_locks_tid(pthread_t tid)
        while( p ) {
                lock_item *lp = p;  p = (lock_item*)p->next;
                if( lp->tid != tid ) continue;
-               lock_table.remove_pointer(lp);  lock_free.append(lp);
+               lock_table.remove_pointer(lp);
+               lp->info->trace = 0;
+               lock_free.append(lp);
        }
        lock_table.unlock();
 }
@@ -291,6 +309,9 @@ void BC_Trace::dump_traces(FILE *fp)
        }
 }
 
+void trace_info::set_owner() { owner = pthread_self(); }
+void trace_info::unset_owner() { owner = 0; }
+
 void BC_Trace::dump_locks(FILE *fp)
 {
 // Dump lock table
@@ -298,9 +319,20 @@ void BC_Trace::dump_locks(FILE *fp)
        fprintf(fp,"signal_entry: lock table size=%d\n", lock_table.size);
        for( trace_item *tp=lock_table.first; tp!=0; tp=tp->next ) {
                lock_item *p=(lock_item*)tp;
-               fprintf(fp,"    %p %s %s %p%s\n", p->info, p->title,
-                       p->loc, (void*)p->tid, p->is_owner ? " *" : "");
+               fprintf(fp,"    %p %s, %s %p%s",
+                       p->info, p->title, p->loc,
+                       (void*)p->tid, p->is_owner ? " *" : "");
+               if( p->info->owner && p->info->owner != p->tid )
+                       fprintf(fp," %p", (void*)p->info->owner);
+               fprintf(fp,"\n");
        }
+       int64_t lock_total = lock_table.total();
+       int64_t free_total = lock_free.total();
+       printf("lock_items: %jd\n", lock_total);
+       printf("lock_frees: %jd\n", free_total);
+       int64_t missed_locks = lock_table.size - (lock_total + free_total);
+       if( missed_locks )
+               printf("miss locks: %jd\n", missed_locks);
 #endif
 }