Back to index

avfs  1.0.1
filecache.c
Go to the documentation of this file.
00001 /*  
00002     AVFS: A Virtual File System Library
00003     Copyright (C) 1998  Miklos Szeredi <miklos@szeredi.hu>
00004     
00005     This program can be distributed under the terms of the GNU GPL.
00006     See the file COPYING.
00007 */
00008 
00009 #include "filecache.h"
00010 #include "internal.h"
00011 #include "exit.h"
00012 
00013 struct filecache {
00014     struct filecache *next;
00015     struct filecache *prev;
00016     
00017     char *key;
00018     void *obj;
00019 };
00020 
00021 static struct filecache fclist;
00022 static AV_LOCK_DECL(fclock);
00023 
00024 static void filecache_remove(struct filecache *fc)
00025 {
00026     struct filecache *prev = fc->prev;
00027     struct filecache *next = fc->next;
00028 
00029     prev->next = next;
00030     next->prev = prev;
00031 }
00032 
00033 static void filecache_insert(struct filecache *fc)
00034 {
00035     struct filecache *prev = &fclist;
00036     struct filecache *next = fclist.next;
00037     
00038     prev->next = fc;
00039     next->prev = fc;
00040     fc->prev = prev;
00041     fc->next = next;
00042 }
00043 
00044 static void filecache_delete(struct filecache *fc)
00045 {
00046     av_log(AVLOG_DEBUG, "FILECACHE: delete <%s>", fc->key);
00047     filecache_remove(fc);
00048 
00049     av_unref_obj(fc->obj);
00050     av_free(fc->key);
00051     av_free(fc);
00052 }
00053 
00054 static struct filecache *filecache_find(const char *key)
00055 {
00056     struct filecache *fc;
00057     
00058     for(fc = fclist.next; fc != &fclist; fc = fc->next) {
00059         if(strcmp(fc->key, key) == 0)
00060             break;
00061     }
00062 
00063     if(fc->obj == NULL)
00064         return NULL;
00065 
00066     return fc;
00067 }
00068 
00069 void *av_filecache_get(const char *key)
00070 {
00071     struct filecache *fc;
00072     void *obj = NULL;
00073     
00074     AV_LOCK(fclock);
00075     fc = filecache_find(key);
00076     if(fc != NULL) {
00077         filecache_remove(fc);
00078         filecache_insert(fc);
00079         obj = fc->obj;
00080         av_ref_obj(obj);
00081     }
00082     AV_UNLOCK(fclock);
00083 
00084     return obj;
00085 }
00086 
00087 void av_filecache_set(const char *key, void *obj)
00088 {
00089     struct filecache *oldfc;
00090     struct filecache *fc;
00091 
00092     if(obj != NULL) {
00093         AV_NEW(fc);
00094         fc->key = av_strdup(key);
00095         fc->obj = obj;
00096         av_ref_obj(obj);
00097     }
00098     else
00099         fc = NULL;
00100 
00101     AV_LOCK(fclock);
00102     oldfc = filecache_find(key);
00103     if(oldfc != NULL)
00104         filecache_delete(oldfc);
00105     if(fc != NULL) {
00106         av_log(AVLOG_DEBUG, "FILECACHE: insert <%s>", key);
00107         filecache_insert(fc);
00108     }
00109     AV_UNLOCK(fclock);
00110 }
00111 
00112 static void destroy_filecache()
00113 {
00114     AV_LOCK(fclock);
00115     while(fclist.next != &fclist)
00116         filecache_delete(fclist.next);
00117     AV_UNLOCK(fclock);
00118 }
00119 
00120 void av_init_filecache()
00121 {
00122     fclist.next = &fclist;
00123     fclist.prev = &fclist;
00124     fclist.obj = NULL;
00125     fclist.key = NULL;
00126     
00127     av_add_exithandler(destroy_filecache);
00128 }
00129 
00130 
00131 int av_filecache_getkey(ventry *ve, char **resp)
00132 {
00133     int res;
00134     char *key;
00135 
00136     res = av_generate_path(ve->mnt->base, &key);
00137     if(res < 0)
00138         return res;
00139 
00140     key = av_stradd(key, AVFS_SEP_STR, ve->mnt->avfs->name, NULL);
00141 
00142     *resp = key;
00143     return 0;
00144 }