]> git.wh0rd.org Git - fontconfig.git/commitdiff
Really fix the global cache: make sure we're reading and writing the same
authorPatrick Lam <plam@MIT.EDU>
Sat, 3 Sep 2005 04:56:56 +0000 (04:56 +0000)
committerPatrick Lam <plam@MIT.EDU>
Sat, 3 Sep 2005 04:56:56 +0000 (04:56 +0000)
    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.

src/fccache.c
src/fccfg.c
src/fcint.h

index fc2fcc6df15e410b3f2b5161ab86c8dd0f9816fa..bc82d714e72350b3da1ce8c96f67a957380a13f9 100644 (file)
@@ -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);
index 0032a9bbf62d52aeca6aa86287dbad50eafd60f6..a14c6b5914e1e096e0fa7e320fab603497af2ebe 100644 (file)
@@ -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:
index b69274c15ee2a18b6aedea8a8e92d52d4cf1889e..e29b447d54a666ebcc8134b965b6c27205b53859 100644 (file)
@@ -427,6 +427,7 @@ FcGlobalCacheReadDir (FcFontSet     *set,
 
 void
 FcGlobalCacheLoad (FcGlobalCache    *cache,
+                   FcStrSet        *staleDirs,
                   const FcChar8    *cache_file);
 
 FcBool