// 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;
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)
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);
}
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();
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 ) {
+ current->Garbage::remove_user();
+ total_lock->unlock();
+ return 0;
}
+ //printf("users: %i \n", users );
+
+ current->Garbage::remove_user();
+ total_lock->unlock();
//printf("check out %p %lx %s\n", current, tid, asset->path);
return current ? current->file : 0;
}
void CICache::remove_all()
{
- CICacheItem *current, *temp;
List<CICacheItem> 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;
}
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();
}