Fix cache algorithm loophole

This closes the door for unneccessary calls to cgit_fill_cache().

Noticed by Linus.

Signed-off-by: Lars Hjemli <hjemli@gmail.com>
This commit is contained in:
Lars Hjemli 2006-12-11 09:57:58 +01:00
parent 76827d8679
commit f5069d88df
3 changed files with 16 additions and 11 deletions

View File

@ -10,7 +10,7 @@
const int NOLOCK = -1; const int NOLOCK = -1;
int cache_lookup(struct cacheitem *item) void cache_prepare(struct cacheitem *item)
{ {
if (!cgit_query_repo) { if (!cgit_query_repo) {
item->name = xstrdup(fmt("%s/index.html", cgit_cache_root)); item->name = xstrdup(fmt("%s/index.html", cgit_cache_root));
@ -30,6 +30,10 @@ int cache_lookup(struct cacheitem *item)
else else
item->ttl = cgit_cache_repo_ttl; item->ttl = cgit_cache_repo_ttl;
} }
}
int cache_exist(struct cacheitem *item)
{
if (stat(item->name, &item->st)) { if (stat(item->name, &item->st)) {
item->st.st_mtime = 0; item->st.st_mtime = 0;
return 0; return 0;

16
cgit.c
View File

@ -465,20 +465,20 @@ static void cgit_fill_cache(struct cacheitem *item)
static void cgit_refresh_cache(struct cacheitem *item) static void cgit_refresh_cache(struct cacheitem *item)
{ {
cache_prepare(item);
top: top:
if (!cache_lookup(item)) { if (!cache_exist(item)) {
if (cache_lock(item)) { if (!cache_lock(item)) {
cgit_fill_cache(item);
cache_unlock(item);
} else {
sched_yield(); sched_yield();
goto top; goto top;
} }
} else if (cache_expired(item)) { if (!cache_exist(item))
if (cache_lock(item)) { cgit_fill_cache(item);
cache_unlock(item);
} else if (cache_expired(item) && cache_lock(item)) {
if (cache_expired(item))
cgit_fill_cache(item); cgit_fill_cache(item);
cache_unlock(item); cache_unlock(item);
}
} }
} }

3
cgit.h
View File

@ -56,9 +56,10 @@ extern void html_link_close(void);
extern int cgit_read_config(const char *filename, configfn fn); extern int cgit_read_config(const char *filename, configfn fn);
extern int cache_lookup(struct cacheitem *item); extern void cache_prepare(struct cacheitem *item);
extern int cache_lock(struct cacheitem *item); extern int cache_lock(struct cacheitem *item);
extern int cache_unlock(struct cacheitem *item); extern int cache_unlock(struct cacheitem *item);
extern int cache_exist(struct cacheitem *item);
extern int cache_expired(struct cacheitem *item); extern int cache_expired(struct cacheitem *item);
#endif /* CGIT_H */ #endif /* CGIT_H */