no longer need ffmpeg patch0 which was for Termux
[goodguy/cinelerra.git] / cinelerra-5.1 / cinelerra / cache.C
index ec219d2180e669e7399d087115180fc766d21c7a..a024fc43645bb362c35c35a8182eb532db9c9db4 100644 (file)
@@ -37,7 +37,7 @@
 
 // edl came from a command which won't exist anymore
 CICache::CICache(Preferences *preferences)
- : List<CICacheItem>()
+ : Garbage("CICache"), List<CICacheItem>()
 {
        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)
@@ -108,12 +108,21 @@ File* CICache::check_out(Asset *asset, EDL *edl, int block)
                        else
                                current = 0;
                }
-               total_lock->unlock();
                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;
 }
@@ -176,7 +185,7 @@ int CICache::delete_entry(char *path)
                while( current && strcmp(current->asset->path, path) !=0 )
                        current = NEXT;
                if( !current ) break;
-               if( current->checked_out ) {
+               if( !current->checked_out ) {
                        remove_pointer(current);
                        break;
                }
@@ -244,36 +253,29 @@ 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 ) {
-               oldest = first;
-               CICacheItem *current = oldest->next;
-               while( current ) {
+       total_lock->lock("CICache::delete_oldest");
+       if( first != last ) { // at least 2
+               CICacheItem *current = first;
+               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;
-                       current = current->next;
+               }
+// delete oldest of at least 2 cache files
+               if( oldest ) {
+                       remove_pointer(oldest);
+                       result = 1;
                }
        }
 // settle for just deleting one frame
-       else if( first )
+       else if( first && !first->checked_out )
                result = first->file->delete_oldest();
-       if( oldest ) {
-// 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 )
-                       remove_pointer(oldest);
-               else
-                       oldest = 0;
-       }
        total_lock->unlock();
-       if( oldest ) {
+       if( oldest )
                oldest->Garbage::remove_user();
-               result = 1;
-       }
        return result;
 }