Use uuid-based cache filename if uuid is assigned to dirs
This commit is contained in:
parent
64895e719d
commit
7b48fd3dd4
|
@ -338,6 +338,14 @@ AM_CONDITIONAL(FREETYPE_PCF_LONG_FAMILY_NAMES, test "x$have_pcf_long_family_name
|
||||||
LIBS="$fontconfig_save_libs"
|
LIBS="$fontconfig_save_libs"
|
||||||
CFLAGS="$fontconfig_save_cflags"
|
CFLAGS="$fontconfig_save_cflags"
|
||||||
|
|
||||||
|
#
|
||||||
|
# Check for uuid
|
||||||
|
#
|
||||||
|
PKG_CHECK_MODULES([UUID], [uuid])
|
||||||
|
PKGCONFIG_REQUIRES_PRIVATELY="$PKGCONFIG_REQUIRES_PRIVATELY uuid"
|
||||||
|
AC_SUBST(UUID_CFLAGS)
|
||||||
|
AC_SUBST(UUID_LIBS)
|
||||||
|
|
||||||
#
|
#
|
||||||
# Check expat configuration
|
# Check expat configuration
|
||||||
#
|
#
|
||||||
|
|
|
@ -77,6 +77,7 @@ AM_CPPFLAGS = \
|
||||||
$(ICONV_CFLAGS) \
|
$(ICONV_CFLAGS) \
|
||||||
$(LIBXML2_CFLAGS) \
|
$(LIBXML2_CFLAGS) \
|
||||||
$(EXPAT_CFLAGS) \
|
$(EXPAT_CFLAGS) \
|
||||||
|
$(UUID_CFLAGS) \
|
||||||
$(WARN_CFLAGS) \
|
$(WARN_CFLAGS) \
|
||||||
-DFC_CACHEDIR='"$(FC_CACHEDIR)"' \
|
-DFC_CACHEDIR='"$(FC_CACHEDIR)"' \
|
||||||
-DFONTCONFIG_PATH='"$(BASECONFIGDIR)"' \
|
-DFONTCONFIG_PATH='"$(BASECONFIGDIR)"' \
|
||||||
|
@ -165,7 +166,7 @@ lib_LTLIBRARIES = libfontconfig.la
|
||||||
libfontconfig_la_LDFLAGS = \
|
libfontconfig_la_LDFLAGS = \
|
||||||
-version-info @LIBT_VERSION_INFO@ -no-undefined $(export_symbols)
|
-version-info @LIBT_VERSION_INFO@ -no-undefined $(export_symbols)
|
||||||
|
|
||||||
libfontconfig_la_LIBADD = $(ICONV_LIBS) $(FREETYPE_LIBS) $(LIBXML2_LIBS) $(EXPAT_LIBS)
|
libfontconfig_la_LIBADD = $(ICONV_LIBS) $(FREETYPE_LIBS) $(LIBXML2_LIBS) $(EXPAT_LIBS) $(UUID_LIBS)
|
||||||
|
|
||||||
libfontconfig_la_DEPENDENCIES = $(fontconfig_def_dependency)
|
libfontconfig_la_DEPENDENCIES = $(fontconfig_def_dependency)
|
||||||
|
|
||||||
|
|
211
src/fccache.c
211
src/fccache.c
|
@ -38,11 +38,188 @@
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
#include <sys/locking.h>
|
#include <sys/locking.h>
|
||||||
#endif
|
#endif
|
||||||
|
#include <uuid/uuid.h>
|
||||||
|
|
||||||
#ifndef O_BINARY
|
#ifndef O_BINARY
|
||||||
#define O_BINARY 0
|
#define O_BINARY 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define FC_UUID_HASH_SIZE 4099
|
||||||
|
|
||||||
|
typedef struct _FcUuidBucket {
|
||||||
|
struct _FcUuidBucket *next;
|
||||||
|
FcChar8 *file;
|
||||||
|
uuid_t uuid;
|
||||||
|
} FcUuidBucket;
|
||||||
|
|
||||||
|
typedef struct _FcUuidHashTable {
|
||||||
|
FcUuidBucket *buckets[FC_UUID_HASH_SIZE];
|
||||||
|
} FcUuidHashTable;
|
||||||
|
|
||||||
|
static FcUuidHashTable uuid_table;
|
||||||
|
|
||||||
|
static FcBool
|
||||||
|
FcCacheUuidAdd (FcUuidHashTable *table,
|
||||||
|
const FcChar8 *file,
|
||||||
|
uuid_t uuid)
|
||||||
|
{
|
||||||
|
FcUuidBucket **prev, *bucket;
|
||||||
|
FcChar32 hash = FcStrHashIgnoreCase (file);
|
||||||
|
|
||||||
|
for (prev = &table->buckets[hash % FC_UUID_HASH_SIZE];
|
||||||
|
(bucket = *prev); prev = &(bucket->next))
|
||||||
|
{
|
||||||
|
if (FcStrCmp (bucket->file, file) == 0)
|
||||||
|
return FcTrue;
|
||||||
|
}
|
||||||
|
bucket = (FcUuidBucket *) malloc (sizeof (FcUuidBucket));
|
||||||
|
if (!bucket)
|
||||||
|
return FcFalse;
|
||||||
|
bucket->next = NULL;
|
||||||
|
bucket->file = FcStrdup (file);
|
||||||
|
uuid_copy (bucket->uuid, uuid);
|
||||||
|
if (!bucket->file)
|
||||||
|
{
|
||||||
|
free (bucket);
|
||||||
|
return FcFalse;
|
||||||
|
}
|
||||||
|
*prev = bucket;
|
||||||
|
|
||||||
|
return FcTrue;
|
||||||
|
}
|
||||||
|
|
||||||
|
static FcBool
|
||||||
|
FcCacheUuidRemove (FcUuidHashTable *table,
|
||||||
|
const FcChar8 *file)
|
||||||
|
{
|
||||||
|
FcUuidBucket **prev, *bucket;
|
||||||
|
FcChar32 hash = FcStrHashIgnoreCase (file);
|
||||||
|
|
||||||
|
for (prev = &table->buckets[hash % FC_UUID_HASH_SIZE];
|
||||||
|
(bucket = *prev); )
|
||||||
|
{
|
||||||
|
if (FcStrCmp (bucket->file, file) == 0)
|
||||||
|
{
|
||||||
|
*prev = bucket->next;
|
||||||
|
FcStrFree (bucket->file);
|
||||||
|
free (bucket);
|
||||||
|
|
||||||
|
return FcTrue;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
prev = &(bucket->next);
|
||||||
|
}
|
||||||
|
return FcFalse;
|
||||||
|
}
|
||||||
|
|
||||||
|
static FcBool
|
||||||
|
FcCacheUuidFind (FcUuidHashTable *table,
|
||||||
|
const FcChar8 *file,
|
||||||
|
uuid_t ret)
|
||||||
|
{
|
||||||
|
FcUuidBucket *bucket;
|
||||||
|
FcChar32 hash = FcStrHashIgnoreCase (file);
|
||||||
|
|
||||||
|
for (bucket = table->buckets[hash % FC_UUID_HASH_SIZE]; bucket; bucket = bucket->next)
|
||||||
|
{
|
||||||
|
if (FcStrCmp (bucket->file, file) == 0)
|
||||||
|
{
|
||||||
|
uuid_copy (ret, bucket->uuid);
|
||||||
|
return FcTrue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return FcFalse;
|
||||||
|
}
|
||||||
|
|
||||||
|
FcBool
|
||||||
|
FcDirCacheCreateUUID (const FcChar8 *dir,
|
||||||
|
FcBool force)
|
||||||
|
{
|
||||||
|
FcBool ret = FcTrue;
|
||||||
|
FcChar8 *uuidname;
|
||||||
|
|
||||||
|
uuidname = FcStrBuildFilename (dir, ".uuid", NULL);
|
||||||
|
if (!uuidname)
|
||||||
|
return FcFalse;
|
||||||
|
|
||||||
|
if (force || access ((const char *) uuidname, F_OK) < 0)
|
||||||
|
{
|
||||||
|
FcAtomic *atomic;
|
||||||
|
int fd;
|
||||||
|
uuid_t uuid;
|
||||||
|
char out[37];
|
||||||
|
|
||||||
|
atomic = FcAtomicCreate (uuidname);
|
||||||
|
if (!atomic)
|
||||||
|
{
|
||||||
|
ret = FcFalse;
|
||||||
|
goto bail1;
|
||||||
|
}
|
||||||
|
if (!FcAtomicLock (atomic))
|
||||||
|
{
|
||||||
|
ret = FcFalse;
|
||||||
|
goto bail2;
|
||||||
|
}
|
||||||
|
fd = FcOpen ((char *)FcAtomicNewFile (atomic), O_RDWR | O_CREAT, 0644);
|
||||||
|
if (fd == -1)
|
||||||
|
{
|
||||||
|
ret = FcFalse;
|
||||||
|
goto bail3;
|
||||||
|
}
|
||||||
|
uuid_generate_random (uuid);
|
||||||
|
FcCacheUuidAdd (&uuid_table, dir, uuid);
|
||||||
|
uuid_unparse (uuid, out);
|
||||||
|
if (FcDebug () & FC_DBG_CACHE)
|
||||||
|
printf ("FcDirCacheCreateUUID %s: %s\n", uuidname, out);
|
||||||
|
write (fd, out, strlen (out));
|
||||||
|
close (fd);
|
||||||
|
FcAtomicReplaceOrig (atomic);
|
||||||
|
bail3:
|
||||||
|
FcAtomicUnlock (atomic);
|
||||||
|
bail2:
|
||||||
|
FcAtomicDestroy (atomic);
|
||||||
|
}
|
||||||
|
bail1:
|
||||||
|
FcStrFree (uuidname);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
FcDirCacheReadUUID (const FcChar8 *dir)
|
||||||
|
{
|
||||||
|
uuid_t uuid;
|
||||||
|
|
||||||
|
if (!FcCacheUuidFind (&uuid_table, dir, uuid))
|
||||||
|
{
|
||||||
|
FcChar8 *uuidname = FcStrBuildFilename (dir, ".uuid", NULL);
|
||||||
|
int fd;
|
||||||
|
|
||||||
|
if ((fd = FcOpen ((char *) uuidname, O_RDONLY)) >= 0)
|
||||||
|
{
|
||||||
|
char suuid[37];
|
||||||
|
|
||||||
|
memset (suuid, 0, sizeof (suuid));
|
||||||
|
if (read (fd, suuid, 36) > 0)
|
||||||
|
{
|
||||||
|
memset (uuid, 0, sizeof (uuid));
|
||||||
|
if (uuid_parse (suuid, uuid) == 0)
|
||||||
|
{
|
||||||
|
if (FcDebug () & FC_DBG_CACHE)
|
||||||
|
printf ("FcDirCacheReadUUID %s -> %s\n", uuidname, suuid);
|
||||||
|
FcCacheUuidAdd (&uuid_table, dir, uuid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
close (fd);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (FcDebug () & FC_DBG_CACHE)
|
||||||
|
printf ("FcDirCacheReadUUID Unable to read %s\n", uuidname);
|
||||||
|
}
|
||||||
|
FcStrFree (uuidname);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
struct MD5Context {
|
struct MD5Context {
|
||||||
FcChar32 buf[4];
|
FcChar32 buf[4];
|
||||||
|
@ -55,7 +232,7 @@ static void MD5Update(struct MD5Context *ctx, const unsigned char *buf, unsigned
|
||||||
static void MD5Final(unsigned char digest[16], struct MD5Context *ctx);
|
static void MD5Final(unsigned char digest[16], struct MD5Context *ctx);
|
||||||
static void MD5Transform(FcChar32 buf[4], FcChar32 in[16]);
|
static void MD5Transform(FcChar32 buf[4], FcChar32 in[16]);
|
||||||
|
|
||||||
#define CACHEBASE_LEN (1 + 32 + 1 + sizeof (FC_ARCHITECTURE) + sizeof (FC_CACHE_SUFFIX))
|
#define CACHEBASE_LEN (1 + 36 + 1 + sizeof (FC_ARCHITECTURE) + sizeof (FC_CACHE_SUFFIX))
|
||||||
|
|
||||||
static FcBool
|
static FcBool
|
||||||
FcCacheIsMmapSafe (int fd)
|
FcCacheIsMmapSafe (int fd)
|
||||||
|
@ -94,7 +271,7 @@ static const char bin2hex[] = { '0', '1', '2', '3',
|
||||||
'c', 'd', 'e', 'f' };
|
'c', 'd', 'e', 'f' };
|
||||||
|
|
||||||
static FcChar8 *
|
static FcChar8 *
|
||||||
FcDirCacheBasename (const FcChar8 * dir, FcChar8 cache_base[CACHEBASE_LEN])
|
FcDirCacheBasenameMD5 (const FcChar8 *dir, FcChar8 cache_base[CACHEBASE_LEN])
|
||||||
{
|
{
|
||||||
unsigned char hash[16];
|
unsigned char hash[16];
|
||||||
FcChar8 *hex_hash;
|
FcChar8 *hex_hash;
|
||||||
|
@ -119,6 +296,20 @@ FcDirCacheBasename (const FcChar8 * dir, FcChar8 cache_base[CACHEBASE_LEN])
|
||||||
return cache_base;
|
return cache_base;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static FcChar8 *
|
||||||
|
FcDirCacheBasenameUUID (const FcChar8 *dir, FcChar8 cache_base[CACHEBASE_LEN])
|
||||||
|
{
|
||||||
|
uuid_t uuid;
|
||||||
|
|
||||||
|
if (FcCacheUuidFind (&uuid_table, dir, uuid))
|
||||||
|
{
|
||||||
|
uuid_unparse (uuid, (char *) cache_base);
|
||||||
|
strcat ((char *) cache_base, "-" FC_ARCHITECTURE FC_CACHE_SUFFIX);
|
||||||
|
return cache_base;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
FcBool
|
FcBool
|
||||||
FcDirCacheUnlink (const FcChar8 *dir, FcConfig *config)
|
FcDirCacheUnlink (const FcChar8 *dir, FcConfig *config)
|
||||||
{
|
{
|
||||||
|
@ -128,7 +319,8 @@ FcDirCacheUnlink (const FcChar8 *dir, FcConfig *config)
|
||||||
FcChar8 *cache_dir;
|
FcChar8 *cache_dir;
|
||||||
const FcChar8 *sysroot = FcConfigGetSysRoot (config);
|
const FcChar8 *sysroot = FcConfigGetSysRoot (config);
|
||||||
|
|
||||||
FcDirCacheBasename (dir, cache_base);
|
if (!FcDirCacheBasenameUUID (dir, cache_base))
|
||||||
|
FcDirCacheBasenameMD5 (dir, cache_base);
|
||||||
|
|
||||||
list = FcStrListCreate (config->cacheDirs);
|
list = FcStrListCreate (config->cacheDirs);
|
||||||
if (!list)
|
if (!list)
|
||||||
|
@ -204,7 +396,8 @@ FcDirCacheProcess (FcConfig *config, const FcChar8 *dir,
|
||||||
}
|
}
|
||||||
FcStrFree (d);
|
FcStrFree (d);
|
||||||
|
|
||||||
FcDirCacheBasename (dir, cache_base);
|
if (!FcDirCacheBasenameUUID (dir, cache_base))
|
||||||
|
FcDirCacheBasenameMD5 (dir, cache_base);
|
||||||
|
|
||||||
list = FcStrListCreate (config->cacheDirs);
|
list = FcStrListCreate (config->cacheDirs);
|
||||||
if (!list)
|
if (!list)
|
||||||
|
@ -534,8 +727,11 @@ FcCacheObjectDereference (void *object)
|
||||||
if (skip)
|
if (skip)
|
||||||
{
|
{
|
||||||
if (FcRefDec (&skip->ref) == 1)
|
if (FcRefDec (&skip->ref) == 1)
|
||||||
|
{
|
||||||
|
FcCacheUuidRemove (&uuid_table, FcCacheDir (skip->cache));
|
||||||
FcDirCacheDisposeUnlocked (skip->cache);
|
FcDirCacheDisposeUnlocked (skip->cache);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
unlock_cache ();
|
unlock_cache ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -797,6 +993,7 @@ FcDirCacheLoad (const FcChar8 *dir, FcConfig *config, FcChar8 **cache_file)
|
||||||
FcDirCacheMapHelper,
|
FcDirCacheMapHelper,
|
||||||
&cache, cache_file))
|
&cache, cache_file))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
FcDirCacheReadUUID (FcCacheDir (cache));
|
||||||
|
|
||||||
return cache;
|
return cache;
|
||||||
}
|
}
|
||||||
|
@ -1049,7 +1246,8 @@ FcDirCacheWrite (FcCache *cache, FcConfig *config)
|
||||||
if (!cache_dir)
|
if (!cache_dir)
|
||||||
return FcFalse;
|
return FcFalse;
|
||||||
|
|
||||||
FcDirCacheBasename (dir, cache_base);
|
if (!FcDirCacheBasenameUUID (dir, cache_base))
|
||||||
|
FcDirCacheBasenameMD5 (dir, cache_base);
|
||||||
cache_hashed = FcStrBuildFilename (cache_dir, cache_base, NULL);
|
cache_hashed = FcStrBuildFilename (cache_dir, cache_base, NULL);
|
||||||
if (!cache_hashed)
|
if (!cache_hashed)
|
||||||
return FcFalse;
|
return FcFalse;
|
||||||
|
@ -1246,7 +1444,8 @@ FcDirCacheLock (const FcChar8 *dir,
|
||||||
const FcChar8 *sysroot = FcConfigGetSysRoot (config);
|
const FcChar8 *sysroot = FcConfigGetSysRoot (config);
|
||||||
int fd = -1;
|
int fd = -1;
|
||||||
|
|
||||||
FcDirCacheBasename (dir, cache_base);
|
if (!FcDirCacheBasenameUUID (dir, cache_base))
|
||||||
|
FcDirCacheBasenameMD5 (dir, cache_base);
|
||||||
list = FcStrListCreate (config->cacheDirs);
|
list = FcStrListCreate (config->cacheDirs);
|
||||||
if (!list)
|
if (!list)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
|
@ -409,6 +409,7 @@ FcDirCacheRead (const FcChar8 *dir, FcBool force, FcConfig *config)
|
||||||
{
|
{
|
||||||
FcCache *cache = NULL;
|
FcCache *cache = NULL;
|
||||||
|
|
||||||
|
FcDirCacheCreateUUID (dir, force);
|
||||||
/* Try to use existing cache file */
|
/* Try to use existing cache file */
|
||||||
if (!force)
|
if (!force)
|
||||||
cache = FcDirCacheLoad (dir, config, NULL);
|
cache = FcDirCacheLoad (dir, config, NULL);
|
||||||
|
|
|
@ -587,6 +587,10 @@ struct _FcValuePromotionBuffer {
|
||||||
|
|
||||||
/* fccache.c */
|
/* fccache.c */
|
||||||
|
|
||||||
|
FcPrivate FcBool
|
||||||
|
FcDirCacheCreateUUID (const FcChar8 *dir,
|
||||||
|
FcBool force);
|
||||||
|
|
||||||
FcPrivate FcCache *
|
FcPrivate FcCache *
|
||||||
FcDirCacheScan (const FcChar8 *dir, FcConfig *config);
|
FcDirCacheScan (const FcChar8 *dir, FcConfig *config);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue