]> git.wh0rd.org - fontconfig.git/blobdiff - src/fccache.c
Was losing local cached dirs in global cache list
[fontconfig.git] / src / fccache.c
index e5e9d14eff729939d0bf9d58ba9b2b247952b39d..538fefedb70e9aa101a3675ce387bce12340d517 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $XFree86: xc/lib/fontconfig/src/fccache.c,v 1.7 2002/05/21 17:06:22 keithp Exp $
+ * $XFree86: xc/lib/fontconfig/src/fccache.c,v 1.12 2002/08/22 07:36:44 keithp Exp $
  *
  * Copyright © 2000 Keith Packard, member of The XFree86 Project, Inc.
  *
 
 #include "fcint.h"
 
+/*
+ * POSIX has broken stdio so that getc must do thread-safe locking,
+ * this is a serious performance problem for applications doing large
+ * amounts of IO with getc (as is done here).  If available, use
+ * the getc_unlocked varient instead.
+ */
+#if defined(getc_unlocked) || defined(_IO_getc_unlocked)
+#define GETC(f) getc_unlocked(f)
+#define PUTC(c,f) putc_unlocked(c,f)
+#else
+#define GETC(f) getc(f)
+#define PUTC(c,f) putc(c,f)
+#endif
+
 #define FC_DBG_CACHE_REF    1024
 
 static FcChar8 *
@@ -35,7 +50,7 @@ FcCacheReadString (FILE *f, FcChar8 *dest, int len)
     int                size;
     int                i;
 
-    while ((c = getc (f)) != EOF)
+    while ((c = GETC (f)) != EOF)
        if (c == '"')
            break;
     if (c == EOF)
@@ -47,7 +62,7 @@ FcCacheReadString (FILE *f, FcChar8 *dest, int len)
     i = 0;
     d = dest;
     escape = FcFalse;
-    while ((c = getc (f)) != EOF)
+    while ((c = GETC (f)) != EOF)
     {
        if (!escape)
        {
@@ -62,7 +77,7 @@ FcCacheReadString (FILE *f, FcChar8 *dest, int len)
        }
        if (i == size)
        {
-           FcChar8 *new = malloc (size * 2);
+           FcChar8 *new = malloc (size * 2);   /* freed in caller */
            if (!new)
                break;
            memcpy (new, d, size);
@@ -87,7 +102,7 @@ FcCacheReadUlong (FILE *f, unsigned long *dest)
     unsigned long   t;
     int                    c;
 
-    while ((c = getc (f)) != EOF)
+    while ((c = GETC (f)) != EOF)
     {
        if (!isspace (c))
            break;
@@ -102,7 +117,7 @@ FcCacheReadUlong (FILE *f, unsigned long *dest)
        if (!isdigit (c))
            return FcFalse;
        t = t * 10 + (c - '0');
-       c = getc (f);
+       c = GETC (f);
     }
     *dest = t;
     return FcTrue;
@@ -141,11 +156,11 @@ FcCacheWriteChars (FILE *f, const FcChar8 *chars)
        switch (c) {
        case '"':
        case '\\':
-           if (putc ('\\', f) == EOF)
+           if (PUTC ('\\', f) == EOF)
                return FcFalse;
            /* fall through */
        default:
-           if (putc (c, f) == EOF)
+           if (PUTC (c, f) == EOF)
                return FcFalse;
        }
     }
@@ -156,11 +171,11 @@ static FcBool
 FcCacheWriteString (FILE *f, const FcChar8 *string)
 {
 
-    if (putc ('"', f) == EOF)
+    if (PUTC ('"', f) == EOF)
        return FcFalse;
     if (!FcCacheWriteChars (f, string))
        return FcFalse;
-    if (putc ('"', f) == EOF)
+    if (PUTC ('"', f) == EOF)
        return FcFalse;
     return FcTrue;
 }
@@ -168,17 +183,17 @@ FcCacheWriteString (FILE *f, const FcChar8 *string)
 static FcBool
 FcCacheWritePath (FILE *f, const FcChar8 *dir, const FcChar8 *file)
 {
-    if (putc ('"', f) == EOF)
+    if (PUTC ('"', f) == EOF)
        return FcFalse;
     if (dir)
        if (!FcCacheWriteChars (f, dir))
            return FcFalse;
     if (dir && dir[strlen((const char *) dir) - 1] != '/')
-       if (putc ('/', f) == EOF)
+       if (PUTC ('/', f) == EOF)
            return FcFalse;
     if (!FcCacheWriteChars (f, file))
        return FcFalse;
-    if (putc ('"', f) == EOF)
+    if (PUTC ('"', f) == EOF)
        return FcFalse;
     return FcTrue;
 }
@@ -200,7 +215,7 @@ FcCacheWriteUlong (FILE *f, unsigned long t)
     while (pow)
     {
        digit = temp / pow;
-       if (putc ((char) digit + '0', f) == EOF)
+       if (PUTC ((char) digit + '0', f) == EOF)
            return FcFalse;
        temp = temp - pow * digit;
        pow = pow / 10;
@@ -232,12 +247,13 @@ FcCacheFontSetAdd (FcFontSet          *set,
     int                len;
     FcBool     ret = FcFalse;
     FcPattern  *font;
+    FcPattern  *frozen;
 
     path = path_buf;
     len = (dir_len + 1 + strlen ((const char *) file) + 1);
     if (len > sizeof (path_buf))
     {
-       path = malloc (len);
+       path = malloc (len);    /* freed down below */
        if (!path)
            return FcFalse;
     }
@@ -262,10 +278,15 @@ FcCacheFontSetAdd (FcFontSet          *set,
        {
            if (FcDebug () & FC_DBG_CACHEV)
                printf (" dir cache file \"%s\"\n", file);
-           ret = (FcPatternAddString (font, FC_FILE, path) &&
-                  FcFontSetAdd (set, font));
-           if (!ret)
-               FcPatternDestroy (font);
+           ret = FcPatternAddString (font, FC_FILE, path);
+           if (ret)
+           {
+               frozen = FcPatternFreeze (font);
+               ret = (frozen != 0);
+               if (ret)
+                  ret = FcFontSetAdd (set, frozen);
+           }
+           FcPatternDestroy (font);
        }
     }
     if (path != path_buf) free (path);
@@ -385,6 +406,7 @@ FcGlobalCacheDirGet (FcGlobalCache  *cache,
        d = malloc (sizeof (FcGlobalCacheDir) + len + 1);
        if (!d)
            return 0;
+       FcMemAlloc (FC_MEM_CACHE, sizeof (FcGlobalCacheDir) + len + 1);
        d->next = *prev;
        *prev = d;
        d->info.hash = hash;
@@ -426,12 +448,11 @@ FcGlobalCacheDirAdd (FcGlobalCache  *cache,
     parent = FcGlobalCacheDirGet (cache, i.dir, i.dir_len, FcTrue);
     if (!parent)
        return 0;
-    subdir = malloc (sizeof (FcGlobalCacheSubdir) + 
-                    strlen ((const char *) i.base) + 1);
+    subdir = malloc (sizeof (FcGlobalCacheSubdir));
     if (!subdir)
        return 0;
-    subdir->file = (FcChar8 *) (subdir + 1);
-    strcpy ((char *) subdir->file, (const char *) i.base);
+    FcMemAlloc (FC_MEM_CACHE, sizeof (FcGlobalCacheSubdir));
+    subdir->ent = d;
     subdir->next = parent->subdirs;
     parent->subdirs = subdir;
     return &d->info;
@@ -448,13 +469,18 @@ FcGlobalCacheDirDestroy (FcGlobalCacheDir *d)
        for (f = d->ents[h]; f; f = next)
        {
            next = f->next;
+           FcMemFree (FC_MEM_CACHE, sizeof (FcGlobalCacheFile) +
+                      strlen ((char *) f->info.file) + 1 +
+                      strlen ((char *) f->name) + 1);
            free (f);
        }
     for (s = d->subdirs; s; s = nexts)
     {
        nexts = s->next;
+       FcMemFree (FC_MEM_CACHE, sizeof (FcGlobalCacheSubdir));
        free (s);
     }
+    FcMemFree (FC_MEM_CACHE, sizeof (FcGlobalCacheDir) + d->len + 1);
     free (d);
 }
 
@@ -505,12 +531,15 @@ FcGlobalCacheScanDir (FcFontSet           *set,
        }
     for (subdir = d->subdirs; subdir; subdir = subdir->next)
     {
+       FcFilePathInfo  info = FcFilePathInfoGet (subdir->ent->info.file);
+       
        if (!FcCacheFontSetAdd (set, dirs, dir, dir_len,
-                               subdir->file, FC_FONT_FILE_DIR))
+                               info.base, FC_FONT_FILE_DIR))
        {
            cache->broken = FcTrue;
            return FcFalse;
        }
+       FcGlobalCacheReferenced (cache, &subdir->ent->info);
     }
     
     FcGlobalCacheReferenced (cache, &d->info);
@@ -566,6 +595,7 @@ FcGlobalCacheFileAdd (FcGlobalCache *cache,
     FcGlobalCacheDir   *d = FcGlobalCacheDirGet (cache, i.dir, 
                                                  i.dir_len, FcTrue);
     FcGlobalCacheFile  *f, **prev;
+    int                        size;
 
     if (!d)
        return 0;
@@ -589,13 +619,18 @@ FcGlobalCacheFileAdd (FcGlobalCache *cache,
        if (f->info.referenced)
            cache->referenced--;
        *prev = f->next;
+       FcMemFree (FC_MEM_CACHE, sizeof (FcGlobalCacheFile) +
+                  strlen ((char *) f->info.file) + 1 +
+                  strlen ((char *) f->name) + 1);
        free (f);
     }
-    f = malloc (sizeof (FcGlobalCacheFile) +
-               strlen ((char *) i.base) + 1 +
-               strlen ((char *) name) + 1);
+    size = (sizeof (FcGlobalCacheFile) +
+           strlen ((char *) i.base) + 1 +
+           strlen ((char *) name) + 1);
+    f = malloc (size);
     if (!f)
        return 0;
+    FcMemAlloc (FC_MEM_CACHE, size);
     f->next = *prev;
     *prev = f;
     f->info.hash = i.base_hash;
@@ -618,11 +653,13 @@ FcGlobalCacheCreate (void)
     cache = malloc (sizeof (FcGlobalCache));
     if (!cache)
        return 0;
+    FcMemAlloc (FC_MEM_CACHE, sizeof (FcGlobalCache));
     for (h = 0; h < FC_GLOBAL_CACHE_DIR_HASH_SIZE; h++)
        cache->ents[h] = 0;
     cache->entries = 0;
     cache->referenced = 0;
     cache->updated = FcFalse;
+    cache->broken = FcFalse;
     return cache;
 }
 
@@ -640,6 +677,7 @@ FcGlobalCacheDestroy (FcGlobalCache *cache)
            FcGlobalCacheDirDestroy (d);
        }
     }
+    FcMemFree (FC_MEM_CACHE, sizeof (FcGlobalCache));
     free (cache);
 }
 
@@ -766,19 +804,19 @@ FcGlobalCacheSave (FcGlobalCache    *cache,
                continue;
            if (!FcCacheWriteString (f, dir->info.file))
                goto bail4;
-           if (putc (' ', f) == EOF)
+           if (PUTC (' ', f) == EOF)
                goto bail4;
            if (!FcCacheWriteInt (f, 0))
                goto bail4;
-           if (putc (' ', f) == EOF)
+           if (PUTC (' ', f) == EOF)
                goto bail4;
            if (!FcCacheWriteTime (f, dir->info.time))
                goto bail4;
-           if (putc (' ', f) == EOF)
+           if (PUTC (' ', f) == EOF)
                goto bail4;
            if (!FcCacheWriteString (f, (FcChar8 *) FC_FONT_FILE_DIR))
                goto bail4;
-           if (putc ('\n', f) == EOF)
+           if (PUTC ('\n', f) == EOF)
                goto bail4;
            
            for (file_hash = 0; file_hash < FC_GLOBAL_CACHE_FILE_HASH_SIZE; file_hash++)
@@ -789,19 +827,19 @@ FcGlobalCacheSave (FcGlobalCache    *cache,
                        continue;
                    if (!FcCacheWritePath (f, dir->info.file, file->info.file))
                        goto bail4;
-                   if (putc (' ', f) == EOF)
+                   if (PUTC (' ', f) == EOF)
                        goto bail4;
                    if (!FcCacheWriteInt (f, file->id < 0 ? 0 : file->id))
                        goto bail4;
-                   if (putc (' ', f) == EOF)
+                   if (PUTC (' ', f) == EOF)
                        goto bail4;
                    if (!FcCacheWriteTime (f, file->info.time))
                        goto bail4;
-                   if (putc (' ', f) == EOF)
+                   if (PUTC (' ', f) == EOF)
                        goto bail4;
                    if (!FcCacheWriteString (f, file->name))
                        goto bail4;
-                   if (putc ('\n', f) == EOF)
+                   if (PUTC ('\n', f) == EOF)
                        goto bail4;
                }
            }
@@ -924,7 +962,7 @@ bail3:
 bail2:
     fclose (f);
 bail1:
-    free (cache_file);
+    FcStrFree (cache_file);
 bail0:
     return ret;
 }
@@ -980,15 +1018,15 @@ FcDirCacheWriteDir (FcFontSet *set, FcStrSet *dirs, const FcChar8 *dir)
        base = FcFileBaseName (cache_file, dir);
        if (!FcCacheWriteString (f, base))
            goto bail3;
-       if (putc (' ', f) == EOF)
+       if (PUTC (' ', f) == EOF)
            goto bail3;
        if (!FcCacheWriteInt (f, 0))
            goto bail3;
-        if (putc (' ', f) == EOF)
+        if (PUTC (' ', f) == EOF)
            goto bail3;
        if (!FcCacheWriteString (f, FC_FONT_FILE_DIR))
            goto bail3;
-       if (putc ('\n', f) == EOF)
+       if (PUTC ('\n', f) == EOF)
            goto bail3;
     }
     
@@ -1004,20 +1042,20 @@ FcDirCacheWriteDir (FcFontSet *set, FcStrSet *dirs, const FcChar8 *dir)
            printf (" write file \"%s\"\n", base);
        if (!FcCacheWriteString (f, base))
            goto bail3;
-       if (putc (' ', f) == EOF)
+       if (PUTC (' ', f) == EOF)
            goto bail3;
        if (!FcCacheWriteInt (f, id))
            goto bail3;
-        if (putc (' ', f) == EOF)
+        if (PUTC (' ', f) == EOF)
            goto bail3;
        name = FcNameUnparse (font);
        if (!name)
            goto bail3;
        ret = FcCacheWriteString (f, name);
-       free (name);
+       FcStrFree (name);
        if (!ret)
            goto bail3;
-       if (putc ('\n', f) == EOF)
+       if (PUTC ('\n', f) == EOF)
            goto bail3;
     }
     
@@ -1026,7 +1064,7 @@ FcDirCacheWriteDir (FcFontSet *set, FcStrSet *dirs, const FcChar8 *dir)
     if (fclose (f) == EOF)
        goto bail1;
     
-    free (cache_file);
+    FcStrFree (cache_file);
 
     if (FcDebug () & FC_DBG_CACHE)
        printf (" cache written\n");
@@ -1038,7 +1076,7 @@ bail2:
     fclose (f);
 bail1:
     unlink ((char *) cache_file);
-    free (cache_file);
+    FcStrFree (cache_file);
 bail0:
     return FcFalse;
 }