From: Patrick Lam Date: Sat, 3 Sep 2005 04:56:56 +0000 (+0000) Subject: Really fix the global cache: make sure we're reading and writing the same X-Git-Tag: fc-2_3_90~13 X-Git-Url: https://git.wh0rd.org/?a=commitdiff_plain;h=03a212e525a34e2ceeac369bac669871d8cc681a;p=fontconfig.git Really fix the global cache: make sure we're reading and writing the same data format. Also match subdirectories when consuming cache information. Also check dates for global cache: a dir is out of date if it is newer than the global cache; scan it manually if that's the case. --- diff --git a/src/fccache.c b/src/fccache.c index fc2fcc6..bc82d71 100644 --- a/src/fccache.c +++ b/src/fccache.c @@ -2,6 +2,7 @@ * $RCSId: xc/lib/fontconfig/src/fccache.c,v 1.12 2002/08/22 07:36:44 keithp Exp $ * * Copyright © 2000 Keith Packard + * Copyright © 2005 Patrick Lam * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that @@ -68,7 +69,7 @@ FcCacheReadString (int fd, FcChar8 *dest, int len) int i; if (len == 0) - return FcFalse; + return 0; size = len; i = 0; @@ -147,6 +148,7 @@ FcGlobalCacheDestroy (FcGlobalCache *cache) void FcGlobalCacheLoad (FcGlobalCache *cache, + FcStrSet *staleDirs, const FcChar8 *cache_file) { FcChar8 name_buf[8192]; @@ -155,6 +157,11 @@ FcGlobalCacheLoad (FcGlobalCache *cache, char candidate_arch_machine_name[MACHINE_SIGNATURE_SIZE + 9]; off_t current_arch_start; + struct stat cache_stat, dir_stat; + + if (stat ((char *) cache_file, &cache_stat) < 0) + return; + cache->fd = open ((char *) cache_file, O_RDONLY); if (cache->fd == -1) return; @@ -168,8 +175,9 @@ FcGlobalCacheLoad (FcGlobalCache *cache, goto bail0; lseek (cache->fd, current_arch_start, SEEK_SET); - if (FcCacheReadString (cache->fd, candidate_arch_machine_name, - sizeof (candidate_arch_machine_name)) == 0) + FcCacheReadString (cache->fd, candidate_arch_machine_name, + sizeof (candidate_arch_machine_name)); + if (strlen(candidate_arch_machine_name) == 0) goto bail0; while (1) @@ -178,6 +186,17 @@ FcGlobalCacheLoad (FcGlobalCache *cache, if (!strlen(name_buf)) break; + if (stat ((char *) name_buf, &dir_stat) < 0 || + dir_stat.st_mtime > cache_stat.st_mtime) + { + FcCache md; + + FcStrSetAdd (staleDirs, FcStrCopy (name_buf)); + read (cache->fd, &md, sizeof (FcCache)); + lseek (cache->fd, FcCacheNextOffset (lseek(cache->fd, 0, SEEK_CUR)) + md.count, SEEK_SET); + continue; + } + d = malloc (sizeof (FcGlobalCacheDir)); if (!d) goto bail1; @@ -210,22 +229,24 @@ FcBool FcGlobalCacheReadDir (FcFontSet *set, FcStrSet *dirs, FcGlobalCache * cache, const FcChar8 *dir, FcConfig *config) { FcGlobalCacheDir *d; + FcBool ret = FcFalse; if (cache->fd == -1) return FcFalse; for (d = cache->dirs; d; d = d->next) { - if (strcmp (d->name, dir) == 0) + if (strncmp (d->name, dir, strlen(dir)) == 0) { lseek (cache->fd, d->offset, SEEK_SET); if (!FcDirCacheConsume (cache->fd, set)) return FcFalse; - return FcTrue; + if (strcmp (d->name, dir) == 0) + ret = FcTrue; } } - return FcFalse; + return ret; } FcBool @@ -302,7 +323,15 @@ FcGlobalCacheSave (FcGlobalCache *cache, if (ftruncate (fd, current_arch_start) == -1) goto bail2; - truncate_to = current_arch_start; + header = malloc (10 + strlen (current_arch_machine_name)); + if (!header) + goto bail1; + sprintf (header, "%8x ", (int)truncate_to); + strcat (header, current_arch_machine_name); + if (!FcCacheWriteString (fd, header)) + goto bail1; + + truncate_to = current_arch_start + strlen(header) + 1; for (dir = cache->dirs; dir; dir = dir->next) { truncate_to += strlen(dir->name) + 1; @@ -311,13 +340,6 @@ FcGlobalCacheSave (FcGlobalCache *cache, truncate_to += dir->metadata.count; } truncate_to -= current_arch_start; - header = malloc (10 + strlen (current_arch_machine_name)); - if (!header) - goto bail1; - sprintf (header, "%8x ", (int)truncate_to); - strcat (header, current_arch_machine_name); - if (!FcCacheWriteString (fd, header)) - goto bail1; for (dir = cache->dirs; dir; dir = dir->next) { @@ -485,8 +507,7 @@ FcCacheReadDirs (FcConfig * config, FcGlobalCache * cache, struct stat statb; /* - * Now scan all of the directories into separate databases - * and write out the results + * Read in the results from 'list'. */ while ((dir = FcStrListNext (list))) { @@ -543,7 +564,7 @@ FcCacheReadDirs (FcConfig * config, FcGlobalCache * cache, if (!FcDirCacheValid (dir) || !FcDirCacheRead (set, subdirs, dir)) { if (FcDebug () & FC_DBG_FONTSET) - printf ("scan dir %s\n", dir); + printf ("cache scan dir %s\n", dir); FcDirScanConfig (set, subdirs, cache, config->blanks, dir, FcFalse, config); diff --git a/src/fccfg.c b/src/fccfg.c index 0032a9b..a14c6b5 100644 --- a/src/fccfg.c +++ b/src/fccfg.c @@ -250,6 +250,7 @@ FcConfigBuildFonts (FcConfig *config) FcFontSet *fonts, *cached_fonts; FcGlobalCache *cache; FcStrList *list; + FcStrSet *oldDirs; FcChar8 *dir; fonts = FcFontSetCreate (); @@ -260,20 +261,24 @@ FcConfigBuildFonts (FcConfig *config) if (!cache) goto bail1; + oldDirs = FcStrSetCreate (); + if (!oldDirs) + goto bail2; + if (config->cache) - FcGlobalCacheLoad (cache, config->cache); + FcGlobalCacheLoad (cache, oldDirs, config->cache); cached_fonts = FcCacheRead(config, cache); if (!cached_fonts) { list = FcConfigGetFontDirs (config); if (!list) - goto bail1; + goto bail2; while ((dir = FcStrListNext (list))) { if (FcDebug () & FC_DBG_FONTSET) - printf ("scan dir %s\n", dir); + printf ("build scan dir %s\n", dir); FcDirScanConfig (fonts, config->fontDirs, cache, config->blanks, dir, FcFalse, config); } @@ -284,6 +289,15 @@ FcConfigBuildFonts (FcConfig *config) { int i; + for (i = 0; i < oldDirs->num; i++) + { + if (FcDebug () & FC_DBG_FONTSET) + printf ("scan dir %s\n", dir); + FcDirScanConfig (fonts, config->fontDirs, cache, + config->blanks, oldDirs->strs[i], + FcFalse, config); + } + for (i = 0; i < cached_fonts->nfont; i++) { if (FcConfigAcceptFont (config, cached_fonts->fonts[i])) @@ -301,10 +315,13 @@ FcConfigBuildFonts (FcConfig *config) if (config->cache) FcGlobalCacheSave (cache, config->cache); FcGlobalCacheDestroy (cache); + FcStrSetDestroy (oldDirs); FcConfigSetFonts (config, fonts, FcSetSystem); return FcTrue; +bail2: + FcStrSetDestroy (oldDirs); bail1: FcFontSetDestroy (fonts); bail0: diff --git a/src/fcint.h b/src/fcint.h index b69274c..e29b447 100644 --- a/src/fcint.h +++ b/src/fcint.h @@ -427,6 +427,7 @@ FcGlobalCacheReadDir (FcFontSet *set, void FcGlobalCacheLoad (FcGlobalCache *cache, + FcStrSet *staleDirs, const FcChar8 *cache_file); FcBool