X-Git-Url: https://git.cinelerra-gg.org/git/?p=goodguy%2Fcinelerra.git;a=blobdiff_plain;f=cinelerra-5.1%2Fcinelerra%2Fcache.C;h=b8e2326dbc823d01aff508590875f8fb0ff420b3;hp=63bb4a0de4b32e9e5b9dcb0480c4f751c0f933c2;hb=refs%2Fheads%2Fmaster;hpb=fbdd13b462256ed4f3b35dc114385fe0b0de0dcd diff --git a/cinelerra-5.1/cinelerra/cache.C b/cinelerra-5.1/cinelerra/cache.C index 63bb4a0d..a024fc43 100644 --- a/cinelerra-5.1/cinelerra/cache.C +++ b/cinelerra-5.1/cinelerra/cache.C @@ -37,7 +37,7 @@ // edl came from a command which won't exist anymore CICache::CICache(Preferences *preferences) - : List() + : Garbage("CICache"), List() { this->preferences = preferences; edl = 0; @@ -69,11 +69,11 @@ File* CICache::check_out(Asset *asset, EDL *edl, int block) CICacheItem *current = 0; long tid = (long)Thread::get_self(); if( !tid ) tid = 1; + total_lock->lock("CICache::check_out"); + add_user(); - while(1) - { + while( users > 1 ) { File *file = 0; - total_lock->lock("CICache::check_out"); // Scan directory for item current = first; while(current && strcmp(current->asset->path, asset->path) != 0) @@ -81,14 +81,10 @@ File* CICache::check_out(Asset *asset, EDL *edl, int block) if(!current) { // Create new item current = new CICacheItem(this, edl, asset); append(current); current->checked_out = tid; - file = current->file; total_lock->unlock(); + file = current->file; int result = file->open_file(preferences, asset, 1, 0); - if( result ) { -SET_TRACE - delete file; - file = 0; - } + if( result ) { delete file; file = 0; } total_lock->lock("CICache::check_out 2"); if( !file ) { remove_pointer(current); @@ -101,7 +97,7 @@ SET_TRACE } else { file = current->file; - if(!current->checked_out) { + if( !current->checked_out ) { // Return existing/new item current->Garbage::add_user(); current->age = EDL::next_id(); @@ -112,12 +108,21 @@ SET_TRACE else current = 0; } - total_lock->unlock(); - if(current || !file || !block) break; + if( current || !file || !block ) break; // Try again after blocking + total_lock->unlock(); check_out_lock->lock("CICache::check_out"); + total_lock->lock("CICache::check_out"); } +// cache deleted during checkout, destroy this + if( users == 1 ) { + remove_user(); + return 0; + } + //printf("users: %i \n", users ); + remove_user(); + total_lock->unlock(); //printf("check out %p %lx %s\n", current, tid, asset->path); return current ? current->file : 0; } @@ -148,42 +153,47 @@ int CICache::check_in(Asset *asset) void CICache::remove_all() { - CICacheItem *current, *temp; List removed; - total_lock->lock("CICache::remove_all"); - for(current=first; current; current=temp) - { - temp = NEXT; -// Must not be checked out because we need the pointer to check back in. -// Really need to give the user the CacheItem. - if(!current->checked_out) - { -//printf("CICache::remove_all: %s\n", current->asset->path); - remove_pointer(current); - removed.append(current); + for(;;) { + total_lock->lock("CICache::remove_all"); + CICacheItem *current = first; + while( current ) { + CICacheItem *next_item = current->next; + if( !current->checked_out ) { + remove_pointer(current); + removed.append(current); + } + current = next_item; } - } - total_lock->unlock(); - while( (current=removed.first) != 0 ) - { - removed.remove_pointer(current); - current->Garbage::remove_user(); + total_lock->unlock(); + while( removed.first ) { + CICacheItem *current = removed.first; + removed.remove_pointer(current); + current->Garbage::remove_user(); + } + if( !first ) break; + check_out_lock->lock(); } } int CICache::delete_entry(char *path) { - total_lock->lock("CICache::delete_entry"); - CICacheItem *current = first; - while( current && strcmp(current->asset->path, path) !=0 ) - current = NEXT; - if(current && !current->checked_out) - remove_pointer(current); - else - current = 0; -//printf("CICache::delete_entry: %s\n", current->asset->path); + CICacheItem *current = 0; + for( ;; ) { + total_lock->lock("CICache::delete_entry"); + current = first; + while( current && strcmp(current->asset->path, path) !=0 ) + current = NEXT; + if( !current ) break; + if( !current->checked_out ) { + remove_pointer(current); + break; + } + total_lock->unlock(); + check_out_lock->lock(); + } total_lock->unlock(); - if(current) + if( current ) current->Garbage::remove_user(); return 0; } @@ -243,46 +253,42 @@ int CICache::get_oldest() int CICache::delete_oldest() { int result = 0; - total_lock->lock("CICache::delete_oldest"); CICacheItem *oldest = 0; -// at least 2 - if( first != last ) { + total_lock->lock("CICache::delete_oldest"); + if( first != last ) { // at least 2 CICacheItem *current = first; - oldest = current; - while( (current=NEXT) != 0 ) { + for( ; !oldest && current; current=current->next ) + if( !current->checked_out ) oldest = current; + for( ; current; current=current->next ) { + if( current->checked_out ) continue; if( current->age < oldest->age ) oldest = current; } -// Got the oldest file. Try requesting cache purge from it. - if( oldest->file ) - oldest->file->purge_cache(); -// Delete the file if cache already empty and not checked out. - if( !oldest->checked_out ) +// delete oldest of at least 2 cache files + if( oldest ) { remove_pointer(oldest); - else - oldest = 0; + result = 1; + } } // settle for just deleting one frame - else if( first ) + else if( first && !first->checked_out ) result = first->file->delete_oldest(); total_lock->unlock(); - if( oldest ) { + if( oldest ) oldest->Garbage::remove_user(); - result = 1; - } return result; } -void CICache::dump() +void CICache::dump(FILE *fp) { CICacheItem *current; total_lock->lock("CICache::dump"); - printf("CICache::dump total size %jd\n", get_memory_usage(0)); + fprintf(fp, "CICache::dump total size %jd\n", get_memory_usage(0)); for(current = first; current; current = NEXT) { - printf("cache item %p asset %p %s age=%d\n", - current, current->asset, - current->asset->path, current->age); + fprintf(fp, "cache item %p asset %p %s age=%d checked_out=%p\n", + current, current->asset, current->asset->path, + current->age, (void*)current->checked_out); } total_lock->unlock(); }