Use FcConfigReference/Destroy appropriately instead of FcConfigGetCurrent
This may improves to be MT-safe. Reported at https://bugs.chromium.org/p/chromium/issues/detail?id=1004254
This commit is contained in:
parent
a45fc8a332
commit
b5bcf61fe7
|
@ -174,6 +174,10 @@ Returns one of the two sets of fonts from the configuration as specified
|
|||
by <parameter>set</parameter>. This font set is owned by the library and must
|
||||
not be modified or freed.
|
||||
If <parameter>config</parameter> is NULL, the current configuration is used.
|
||||
</para><para>
|
||||
This function isn't MT-safe. <function>FcConfigReference</function> must be called
|
||||
before using this and then <function>FcConfigDestroy</function> when
|
||||
the return value is no longer referenced.
|
||||
@@
|
||||
|
||||
@RET@ FcBlanks *
|
||||
|
@ -407,6 +411,10 @@ parse error, semantic error or allocation failure. Otherwise returns FcTrue.
|
|||
Obtains the system root directory in 'config' if available. All files
|
||||
(including file properties in patterns) obtained from this 'config' are
|
||||
relative to this system root directory.
|
||||
</para><para>
|
||||
This function isn't MT-safe. <function>FcConfigReference</function> must be called
|
||||
before using this and then <function>FcConfigDestroy</function> when
|
||||
the return value is no longer referenced.
|
||||
@SINCE@ 2.10.92
|
||||
@@
|
||||
|
||||
|
@ -433,6 +441,10 @@ When setting this on the current config this causes changing current config
|
|||
@PURPOSE@ Initialize the iterator
|
||||
@DESC@
|
||||
Initialize 'iter' with the first iterator in the config file information list.
|
||||
</para><para>
|
||||
This function isn't MT-safe. <function>FcConfigReference</function> must be called
|
||||
before using this and then <function>FcConfigDestroy</function> when the relevant
|
||||
values are no longer referenced.
|
||||
@SINCE@ 2.12.91
|
||||
@@
|
||||
|
||||
|
@ -444,6 +456,10 @@ Initialize 'iter' with the first iterator in the config file information list.
|
|||
@DESC@
|
||||
Set 'iter' to point to the next node in the config file information list.
|
||||
If there is no next node, FcFalse is returned.
|
||||
</para><para>
|
||||
This function isn't MT-safe. <function>FcConfigReference</function> must be called
|
||||
before using <function>FcConfigFileInfoIterInit</function> and then
|
||||
<function>FcConfigDestroy</function> when the relevant values are no longer referenced.
|
||||
@SINCE@ 2.12.91
|
||||
@@
|
||||
|
||||
|
@ -459,5 +475,9 @@ If there is no next node, FcFalse is returned.
|
|||
Obtain the filename, the description and the flag whether it is enabled or not
|
||||
for 'iter' where points to current configuration file information.
|
||||
If the iterator is invalid, FcFalse is returned.
|
||||
</para><para>
|
||||
This function isn't MT-safe. <function>FcConfigReference</function> must be called
|
||||
before using <function>FcConfigFileInfoIterInit</function> and then
|
||||
<function>FcConfigDestroy</function> when the relevant values are no longer referenced.
|
||||
@SINCE@ 2.12.91
|
||||
@@
|
||||
|
|
|
@ -375,7 +375,7 @@ FcPublic FcBool
|
|||
FcDirCacheClean (const FcChar8 *cache_dir, FcBool verbose);
|
||||
|
||||
FcPublic void
|
||||
FcCacheCreateTagFile (const FcConfig *config);
|
||||
FcCacheCreateTagFile (FcConfig *config);
|
||||
|
||||
FcPublic FcBool
|
||||
FcDirCacheCreateUUID (FcChar8 *dir,
|
||||
|
@ -437,7 +437,7 @@ FcPublic FcBlanks *
|
|||
FcConfigGetBlanks (FcConfig *config);
|
||||
|
||||
FcPublic FcStrList *
|
||||
FcConfigGetCacheDirs (const FcConfig *config);
|
||||
FcConfigGetCacheDirs (FcConfig *config);
|
||||
|
||||
FcPublic int
|
||||
FcConfigGetRescanInterval (FcConfig *config);
|
||||
|
|
|
@ -58,11 +58,15 @@ FcDirCacheDeleteUUID (const FcChar8 *dir,
|
|||
{
|
||||
FcBool ret = FcTrue;
|
||||
#ifndef _WIN32
|
||||
const FcChar8 *sysroot = FcConfigGetSysRoot (config);
|
||||
const FcChar8 *sysroot;
|
||||
FcChar8 *target, *d;
|
||||
struct stat statb;
|
||||
struct timeval times[2];
|
||||
|
||||
config = FcConfigReference (config);
|
||||
if (!config)
|
||||
return FcFalse;
|
||||
sysroot = FcConfigGetSysRoot (config);
|
||||
if (sysroot)
|
||||
d = FcStrBuildFilename (sysroot, dir, NULL);
|
||||
else
|
||||
|
@ -94,6 +98,7 @@ FcDirCacheDeleteUUID (const FcChar8 *dir,
|
|||
bail:
|
||||
FcStrFree (d);
|
||||
#endif
|
||||
FcConfigDestroy (config);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -265,7 +270,13 @@ FcDirCacheUnlink (const FcChar8 *dir, FcConfig *config)
|
|||
#endif
|
||||
FcStrList *list;
|
||||
FcChar8 *cache_dir;
|
||||
const FcChar8 *sysroot = FcConfigGetSysRoot (config);
|
||||
const FcChar8 *sysroot;
|
||||
FcBool ret = FcTrue;
|
||||
|
||||
config = FcConfigReference (config);
|
||||
if (!config)
|
||||
return FcFalse;
|
||||
sysroot = FcConfigGetSysRoot (config);
|
||||
|
||||
FcDirCacheBasenameMD5 (config, dir, cache_base);
|
||||
#ifndef _WIN32
|
||||
|
@ -274,7 +285,10 @@ FcDirCacheUnlink (const FcChar8 *dir, FcConfig *config)
|
|||
|
||||
list = FcStrListCreate (config->cacheDirs);
|
||||
if (!list)
|
||||
return FcFalse;
|
||||
{
|
||||
ret = FcFalse;
|
||||
goto bail;
|
||||
}
|
||||
|
||||
while ((cache_dir = FcStrListNext (list)))
|
||||
{
|
||||
|
@ -304,8 +318,11 @@ FcDirCacheUnlink (const FcChar8 *dir, FcConfig *config)
|
|||
FcDirCacheDeleteUUID (dir, config);
|
||||
/* return FcFalse if something went wrong */
|
||||
if (cache_dir)
|
||||
return FcFalse;
|
||||
return FcTrue;
|
||||
ret = FcFalse;
|
||||
bail:
|
||||
FcConfigDestroy (config);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -1041,10 +1058,15 @@ FcDirCacheLoad (const FcChar8 *dir, FcConfig *config, FcChar8 **cache_file)
|
|||
{
|
||||
FcCache *cache = NULL;
|
||||
|
||||
config = FcConfigReference (config);
|
||||
if (!config)
|
||||
return NULL;
|
||||
if (!FcDirCacheProcess (config, dir,
|
||||
FcDirCacheMapHelper,
|
||||
&cache, cache_file))
|
||||
return NULL;
|
||||
cache = NULL;
|
||||
|
||||
FcConfigDestroy (config);
|
||||
|
||||
return cache;
|
||||
}
|
||||
|
@ -1055,13 +1077,16 @@ FcDirCacheLoadFile (const FcChar8 *cache_file, struct stat *file_stat)
|
|||
int fd;
|
||||
FcCache *cache;
|
||||
struct stat my_file_stat;
|
||||
FcConfig *config;
|
||||
|
||||
if (!file_stat)
|
||||
file_stat = &my_file_stat;
|
||||
fd = FcDirCacheOpenFile (cache_file, file_stat);
|
||||
if (fd < 0)
|
||||
return NULL;
|
||||
cache = FcDirCacheMapFd (FcConfigGetCurrent (), fd, file_stat, NULL);
|
||||
config = FcConfigReference (NULL);
|
||||
cache = FcDirCacheMapFd (config, fd, file_stat, NULL);
|
||||
FcConfigDestroy (config);
|
||||
close (fd);
|
||||
return cache;
|
||||
}
|
||||
|
@ -1155,12 +1180,16 @@ FcBool
|
|||
FcDirCacheValid (const FcChar8 *dir)
|
||||
{
|
||||
FcConfig *config;
|
||||
FcBool ret;
|
||||
|
||||
config = FcConfigGetCurrent ();
|
||||
config = FcConfigReference (NULL);
|
||||
if (!config)
|
||||
return FcFalse;
|
||||
|
||||
return FcDirCacheValidConfig (dir, config);
|
||||
ret = FcDirCacheValidConfig (dir, config);
|
||||
FcConfigDestroy (config);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1438,9 +1467,13 @@ FcDirCacheClean (const FcChar8 *cache_dir, FcBool verbose)
|
|||
FcCache *cache;
|
||||
struct stat target_stat;
|
||||
const FcChar8 *sysroot;
|
||||
FcConfig *config;
|
||||
|
||||
config = FcConfigReference (NULL);
|
||||
if (!config)
|
||||
return FcFalse;
|
||||
/* FIXME: this API needs to support non-current FcConfig */
|
||||
sysroot = FcConfigGetSysRoot (NULL);
|
||||
sysroot = FcConfigGetSysRoot (config);
|
||||
if (sysroot)
|
||||
dir = FcStrBuildFilename (sysroot, cache_dir, NULL);
|
||||
else
|
||||
|
@ -1448,7 +1481,8 @@ FcDirCacheClean (const FcChar8 *cache_dir, FcBool verbose)
|
|||
if (!dir)
|
||||
{
|
||||
fprintf (stderr, "Fontconfig error: %s: out of memory\n", cache_dir);
|
||||
return FcFalse;
|
||||
ret = FcFalse;
|
||||
goto bail;
|
||||
}
|
||||
if (access ((char *) dir, W_OK) != 0)
|
||||
{
|
||||
|
@ -1525,8 +1559,10 @@ FcDirCacheClean (const FcChar8 *cache_dir, FcBool verbose)
|
|||
}
|
||||
|
||||
closedir (d);
|
||||
bail0:
|
||||
bail0:
|
||||
FcStrFree (dir);
|
||||
bail:
|
||||
FcConfigDestroy (config);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -1968,15 +2004,20 @@ FcDirCacheCreateTagFile (const FcChar8 *cache_dir)
|
|||
}
|
||||
|
||||
void
|
||||
FcCacheCreateTagFile (const FcConfig *config)
|
||||
FcCacheCreateTagFile (FcConfig *config)
|
||||
{
|
||||
FcChar8 *cache_dir = NULL, *d = NULL;
|
||||
FcStrList *list;
|
||||
const FcChar8 *sysroot = FcConfigGetSysRoot (config);
|
||||
const FcChar8 *sysroot;
|
||||
|
||||
config = FcConfigReference (config);
|
||||
if (!config)
|
||||
return;
|
||||
sysroot = FcConfigGetSysRoot (config);
|
||||
|
||||
list = FcConfigGetCacheDirs (config);
|
||||
if (!list)
|
||||
return;
|
||||
goto bail;
|
||||
|
||||
while ((cache_dir = FcStrListNext (list)))
|
||||
{
|
||||
|
@ -1992,6 +2033,8 @@ FcCacheCreateTagFile (const FcConfig *config)
|
|||
if (d)
|
||||
FcStrFree (d);
|
||||
FcStrListDone (list);
|
||||
bail:
|
||||
FcConfigDestroy (config);
|
||||
}
|
||||
|
||||
#define __fccache__
|
||||
|
|
237
src/fccfg.c
237
src/fccfg.c
|
@ -237,12 +237,12 @@ FcConfigUptoDate (FcConfig *config)
|
|||
{
|
||||
FcFileTime config_time, config_dir_time, font_time;
|
||||
time_t now = time(0);
|
||||
FcBool ret = FcTrue;
|
||||
|
||||
config = FcConfigReference (config);
|
||||
if (!config)
|
||||
{
|
||||
config = FcConfigGetCurrent ();
|
||||
if (!config)
|
||||
return FcFalse;
|
||||
}
|
||||
return FcFalse;
|
||||
|
||||
config_time = FcConfigNewestFile (config->configFiles);
|
||||
config_dir_time = FcConfigNewestFile (config->configDirs);
|
||||
font_time = FcConfigNewestFile (config->fontDirs);
|
||||
|
@ -258,13 +258,19 @@ FcConfigUptoDate (FcConfig *config)
|
|||
fprintf (stderr,
|
||||
"Fontconfig warning: Directory/file mtime in the future. New fonts may not be detected.\n");
|
||||
config->rescanTime = now;
|
||||
return FcTrue;
|
||||
goto bail;
|
||||
}
|
||||
else
|
||||
return FcFalse;
|
||||
{
|
||||
ret = FcFalse;
|
||||
goto bail;
|
||||
}
|
||||
}
|
||||
config->rescanTime = now;
|
||||
return FcTrue;
|
||||
bail:
|
||||
FcConfigDestroy (config);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
FcExpr *
|
||||
|
@ -291,11 +297,26 @@ FcConfigReference (FcConfig *config)
|
|||
{
|
||||
if (!config)
|
||||
{
|
||||
config = FcConfigGetCurrent ();
|
||||
/* Do not use FcConfigGetCurrent () for the purpose of obtaining current FcConfig here.
|
||||
* because the reference counter must be increased before setting it to _fcConfig.
|
||||
*/
|
||||
retry:
|
||||
config = fc_atomic_ptr_get (&_fcConfig);
|
||||
if (!config)
|
||||
return 0;
|
||||
}
|
||||
{
|
||||
config = FcConfigCreate ();
|
||||
FcRefInc (&config->ref);
|
||||
|
||||
config = FcInitLoadOwnConfigAndFonts (config);
|
||||
if (!fc_atomic_ptr_cmpexch (&_fcConfig, NULL, config))
|
||||
{
|
||||
FcConfigDestroy (config); /* To decrease the refcount for the above one. */
|
||||
FcConfigDestroy (config); /* To destroy it actualy */
|
||||
goto retry;
|
||||
}
|
||||
return config;
|
||||
}
|
||||
}
|
||||
FcRefInc (&config->ref);
|
||||
|
||||
return config;
|
||||
|
@ -475,25 +496,32 @@ FcBool
|
|||
FcConfigBuildFonts (FcConfig *config)
|
||||
{
|
||||
FcFontSet *fonts;
|
||||
FcBool ret = FcTrue;
|
||||
|
||||
config = FcConfigReference (config);
|
||||
if (!config)
|
||||
{
|
||||
config = FcConfigGetCurrent ();
|
||||
if (!config)
|
||||
return FcFalse;
|
||||
}
|
||||
return FcFalse;
|
||||
|
||||
fonts = FcFontSetCreate ();
|
||||
if (!fonts)
|
||||
return FcFalse;
|
||||
{
|
||||
ret = FcFalse;
|
||||
goto bail;
|
||||
}
|
||||
|
||||
FcConfigSetFonts (config, fonts, FcSetSystem);
|
||||
|
||||
if (!FcConfigAddDirList (config, FcSetSystem, config->fontDirs))
|
||||
return FcFalse;
|
||||
{
|
||||
ret = FcFalse;
|
||||
goto bail;
|
||||
}
|
||||
if (FcDebug () & FC_DBG_FONTSET)
|
||||
FcFontSetPrint (fonts);
|
||||
return FcTrue;
|
||||
bail:
|
||||
FcConfigDestroy (config);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
FcBool
|
||||
|
@ -537,13 +565,15 @@ FcConfigAddConfigDir (FcConfig *config,
|
|||
FcStrList *
|
||||
FcConfigGetConfigDirs (FcConfig *config)
|
||||
{
|
||||
FcStrList *ret;
|
||||
|
||||
config = FcConfigReference (config);
|
||||
if (!config)
|
||||
{
|
||||
config = FcConfigGetCurrent ();
|
||||
if (!config)
|
||||
return 0;
|
||||
}
|
||||
return FcStrListCreate (config->configDirs);
|
||||
return NULL;
|
||||
ret = FcStrListCreate (config->configDirs);
|
||||
FcConfigDestroy (config);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
FcBool
|
||||
|
@ -579,13 +609,15 @@ FcConfigResetFontDirs (FcConfig *config)
|
|||
FcStrList *
|
||||
FcConfigGetFontDirs (FcConfig *config)
|
||||
{
|
||||
FcStrList *ret;
|
||||
|
||||
config = FcConfigReference (config);
|
||||
if (!config)
|
||||
{
|
||||
config = FcConfigGetCurrent ();
|
||||
if (!config)
|
||||
return 0;
|
||||
}
|
||||
return FcStrListCreate (config->fontDirs);
|
||||
return NULL;
|
||||
ret = FcStrListCreate (config->fontDirs);
|
||||
FcConfigDestroy (config);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static FcBool
|
||||
|
@ -670,15 +702,17 @@ FcConfigAddCacheDir (FcConfig *config,
|
|||
}
|
||||
|
||||
FcStrList *
|
||||
FcConfigGetCacheDirs (const FcConfig *config)
|
||||
FcConfigGetCacheDirs (FcConfig *config)
|
||||
{
|
||||
FcStrList *ret;
|
||||
|
||||
config = FcConfigReference (config);
|
||||
if (!config)
|
||||
{
|
||||
config = FcConfigGetCurrent ();
|
||||
if (!config)
|
||||
return 0;
|
||||
}
|
||||
return FcStrListCreate (config->cacheDirs);
|
||||
return NULL;
|
||||
ret = FcStrListCreate (config->cacheDirs);
|
||||
FcConfigDestroy (config);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
FcBool
|
||||
|
@ -699,13 +733,15 @@ FcConfigAddConfigFile (FcConfig *config,
|
|||
FcStrList *
|
||||
FcConfigGetConfigFiles (FcConfig *config)
|
||||
{
|
||||
FcStrList *ret;
|
||||
|
||||
config = FcConfigReference (config);
|
||||
if (!config)
|
||||
{
|
||||
config = FcConfigGetCurrent ();
|
||||
if (!config)
|
||||
return 0;
|
||||
}
|
||||
return FcStrListCreate (config->configFiles);
|
||||
return NULL;
|
||||
ret = FcStrListCreate (config->configFiles);
|
||||
FcConfigDestroy (config);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
FcChar8 *
|
||||
|
@ -784,25 +820,26 @@ FcConfigAddBlank (FcConfig *config FC_UNUSED,
|
|||
int
|
||||
FcConfigGetRescanInterval (FcConfig *config)
|
||||
{
|
||||
int ret;
|
||||
|
||||
config = FcConfigReference (config);
|
||||
if (!config)
|
||||
{
|
||||
config = FcConfigGetCurrent ();
|
||||
if (!config)
|
||||
return 0;
|
||||
}
|
||||
return config->rescanInterval;
|
||||
return 0;
|
||||
ret = config->rescanInterval;
|
||||
FcConfigDestroy (config);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
FcBool
|
||||
FcConfigSetRescanInterval (FcConfig *config, int rescanInterval)
|
||||
{
|
||||
config = FcConfigReference (config);
|
||||
if (!config)
|
||||
{
|
||||
config = FcConfigGetCurrent ();
|
||||
if (!config)
|
||||
return FcFalse;
|
||||
}
|
||||
return FcFalse;
|
||||
config->rescanInterval = rescanInterval;
|
||||
FcConfigDestroy (config);
|
||||
|
||||
return FcTrue;
|
||||
}
|
||||
|
||||
|
@ -1670,15 +1707,13 @@ FcConfigSubstituteWithPat (FcConfig *config,
|
|||
FcBool retval = FcTrue;
|
||||
FcTest **tst = NULL;
|
||||
|
||||
if (!config)
|
||||
{
|
||||
config = FcConfigGetCurrent ();
|
||||
if (!config)
|
||||
return FcFalse;
|
||||
}
|
||||
|
||||
if (kind < FcMatchKindBegin || kind >= FcMatchKindEnd)
|
||||
return FcFalse;
|
||||
|
||||
config = FcConfigReference (config);
|
||||
if (!config)
|
||||
return FcFalse;
|
||||
|
||||
s = config->subst[kind];
|
||||
if (kind == FcMatchPattern)
|
||||
{
|
||||
|
@ -1973,6 +2008,7 @@ bail1:
|
|||
free (value);
|
||||
if (tst)
|
||||
free (tst);
|
||||
FcConfigDestroy (config);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
@ -2290,12 +2326,9 @@ FcConfigGetFilename (FcConfig *config,
|
|||
FcChar8 *file, *dir, **path, **p;
|
||||
const FcChar8 *sysroot;
|
||||
|
||||
config = FcConfigReference (config);
|
||||
if (!config)
|
||||
{
|
||||
config = FcConfigGetCurrent ();
|
||||
if (!config)
|
||||
return NULL;
|
||||
}
|
||||
return NULL;
|
||||
sysroot = FcConfigGetSysRoot (config);
|
||||
if (!url || !*url)
|
||||
{
|
||||
|
@ -2306,7 +2339,10 @@ FcConfigGetFilename (FcConfig *config,
|
|||
file = 0;
|
||||
|
||||
if (FcStrIsAbsoluteFilename(url))
|
||||
return FcConfigFileExists (sysroot, url);
|
||||
{
|
||||
file = FcConfigFileExists (sysroot, url);
|
||||
goto bail;
|
||||
}
|
||||
|
||||
if (*url == '~')
|
||||
{
|
||||
|
@ -2330,7 +2366,10 @@ FcConfigGetFilename (FcConfig *config,
|
|||
{
|
||||
path = FcConfigGetPath ();
|
||||
if (!path)
|
||||
return NULL;
|
||||
{
|
||||
file = NULL;
|
||||
goto bail;
|
||||
}
|
||||
for (p = path; *p; p++)
|
||||
{
|
||||
FcChar8 *s;
|
||||
|
@ -2347,6 +2386,9 @@ FcConfigGetFilename (FcConfig *config,
|
|||
}
|
||||
FcConfigFreePath (path);
|
||||
}
|
||||
bail:
|
||||
FcConfigDestroy (config);
|
||||
|
||||
return file;
|
||||
}
|
||||
|
||||
|
@ -2409,17 +2451,18 @@ FcConfigAppFontAddFile (FcConfig *config,
|
|||
FcStrSet *subdirs;
|
||||
FcStrList *sublist;
|
||||
FcChar8 *subdir;
|
||||
FcBool ret = FcTrue;
|
||||
|
||||
config = FcConfigReference (config);
|
||||
if (!config)
|
||||
{
|
||||
config = FcConfigGetCurrent ();
|
||||
if (!config)
|
||||
return FcFalse;
|
||||
}
|
||||
return FcFalse;
|
||||
|
||||
subdirs = FcStrSetCreateEx (FCSS_GROW_BY_64);
|
||||
if (!subdirs)
|
||||
return FcFalse;
|
||||
{
|
||||
ret = FcFalse;
|
||||
goto bail;
|
||||
}
|
||||
|
||||
set = FcConfigGetFonts (config, FcSetApplication);
|
||||
if (!set)
|
||||
|
@ -2428,7 +2471,8 @@ FcConfigAppFontAddFile (FcConfig *config,
|
|||
if (!set)
|
||||
{
|
||||
FcStrSetDestroy (subdirs);
|
||||
return FcFalse;
|
||||
ret = FcFalse;
|
||||
goto bail;
|
||||
}
|
||||
FcConfigSetFonts (config, set, FcSetApplication);
|
||||
}
|
||||
|
@ -2436,7 +2480,8 @@ FcConfigAppFontAddFile (FcConfig *config,
|
|||
if (!FcFileScanConfig (set, subdirs, file, config))
|
||||
{
|
||||
FcStrSetDestroy (subdirs);
|
||||
return FcFalse;
|
||||
ret = FcFalse;
|
||||
goto bail;
|
||||
}
|
||||
if ((sublist = FcStrListCreate (subdirs)))
|
||||
{
|
||||
|
@ -2447,7 +2492,10 @@ FcConfigAppFontAddFile (FcConfig *config,
|
|||
FcStrListDone (sublist);
|
||||
}
|
||||
FcStrSetDestroy (subdirs);
|
||||
return FcTrue;
|
||||
bail:
|
||||
FcConfigDestroy (config);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
FcBool
|
||||
|
@ -2456,17 +2504,18 @@ FcConfigAppFontAddDir (FcConfig *config,
|
|||
{
|
||||
FcFontSet *set;
|
||||
FcStrSet *dirs;
|
||||
FcBool ret = FcTrue;
|
||||
|
||||
config = FcConfigReference (config);
|
||||
if (!config)
|
||||
{
|
||||
config = FcConfigGetCurrent ();
|
||||
if (!config)
|
||||
return FcFalse;
|
||||
}
|
||||
return FcFalse;
|
||||
|
||||
dirs = FcStrSetCreateEx (FCSS_GROW_BY_64);
|
||||
if (!dirs)
|
||||
return FcFalse;
|
||||
{
|
||||
ret = FcFalse;
|
||||
goto bail;
|
||||
}
|
||||
|
||||
set = FcConfigGetFonts (config, FcSetApplication);
|
||||
if (!set)
|
||||
|
@ -2475,7 +2524,8 @@ FcConfigAppFontAddDir (FcConfig *config,
|
|||
if (!set)
|
||||
{
|
||||
FcStrSetDestroy (dirs);
|
||||
return FcFalse;
|
||||
ret = FcFalse;
|
||||
goto bail;
|
||||
}
|
||||
FcConfigSetFonts (config, set, FcSetApplication);
|
||||
}
|
||||
|
@ -2485,23 +2535,26 @@ FcConfigAppFontAddDir (FcConfig *config,
|
|||
if (!FcConfigAddDirList (config, FcSetApplication, dirs))
|
||||
{
|
||||
FcStrSetDestroy (dirs);
|
||||
return FcFalse;
|
||||
ret = FcFalse;
|
||||
goto bail;
|
||||
}
|
||||
FcStrSetDestroy (dirs);
|
||||
return FcTrue;
|
||||
bail:
|
||||
FcConfigDestroy (config);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
FcConfigAppFontClear (FcConfig *config)
|
||||
{
|
||||
config = FcConfigReference (config);
|
||||
if (!config)
|
||||
{
|
||||
config = FcConfigGetCurrent ();
|
||||
if (!config)
|
||||
return;
|
||||
}
|
||||
return;
|
||||
|
||||
FcConfigSetFonts (config, 0, FcSetApplication);
|
||||
|
||||
FcConfigDestroy (config);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
31
src/fcdir.c
31
src/fcdir.c
|
@ -167,7 +167,16 @@ FcFileScan (FcFontSet *set,
|
|||
const FcChar8 *file,
|
||||
FcBool force FC_UNUSED)
|
||||
{
|
||||
return FcFileScanConfig (set, dirs, file, FcConfigGetCurrent ());
|
||||
FcConfig *config;
|
||||
FcBool ret;
|
||||
|
||||
config = FcConfigReference (NULL);
|
||||
if (!config)
|
||||
return FcFalse;
|
||||
ret = FcFileScanConfig (set, dirs, file, config);
|
||||
FcConfigDestroy (config);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -271,10 +280,19 @@ FcDirScan (FcFontSet *set,
|
|||
const FcChar8 *dir,
|
||||
FcBool force FC_UNUSED)
|
||||
{
|
||||
FcConfig *config;
|
||||
FcBool ret;
|
||||
|
||||
if (cache || !force)
|
||||
return FcFalse;
|
||||
|
||||
return FcDirScanConfig (set, dirs, dir, force, FcConfigGetCurrent ());
|
||||
config = FcConfigReference (NULL);
|
||||
if (!config)
|
||||
return FcFalse;
|
||||
ret = FcDirScanConfig (set, dirs, dir, force, config);
|
||||
FcConfigDestroy (config);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -353,12 +371,16 @@ FcDirCacheRescan (const FcChar8 *dir, FcConfig *config)
|
|||
FcCache *new = NULL;
|
||||
struct stat dir_stat;
|
||||
FcStrSet *dirs;
|
||||
const FcChar8 *sysroot = FcConfigGetSysRoot (config);
|
||||
const FcChar8 *sysroot;
|
||||
FcChar8 *d = NULL;
|
||||
#ifndef _WIN32
|
||||
int fd = -1;
|
||||
#endif
|
||||
|
||||
config = FcConfigReference (config);
|
||||
if (!config)
|
||||
return NULL;
|
||||
sysroot = FcConfigGetSysRoot (config);
|
||||
cache = FcDirCacheLoad (dir, config, NULL);
|
||||
if (!cache)
|
||||
goto bail;
|
||||
|
@ -401,6 +423,7 @@ bail1:
|
|||
bail:
|
||||
if (d)
|
||||
FcStrFree (d);
|
||||
FcConfigDestroy (config);
|
||||
|
||||
return new;
|
||||
}
|
||||
|
@ -413,6 +436,7 @@ FcDirCacheRead (const FcChar8 *dir, FcBool force, FcConfig *config)
|
|||
{
|
||||
FcCache *cache = NULL;
|
||||
|
||||
config = FcConfigReference (config);
|
||||
/* Try to use existing cache file */
|
||||
if (!force)
|
||||
cache = FcDirCacheLoad (dir, config, NULL);
|
||||
|
@ -420,6 +444,7 @@ FcDirCacheRead (const FcChar8 *dir, FcBool force, FcConfig *config)
|
|||
/* Not using existing cache file, construct new cache */
|
||||
if (!cache)
|
||||
cache = FcDirCacheScan (dir, config);
|
||||
FcConfigDestroy (config);
|
||||
|
||||
return cache;
|
||||
}
|
||||
|
|
15
src/fcinit.c
15
src/fcinit.c
|
@ -229,7 +229,8 @@ FcInitReinitialize (void)
|
|||
FcBool
|
||||
FcInitBringUptoDate (void)
|
||||
{
|
||||
FcConfig *config = FcConfigGetCurrent ();
|
||||
FcConfig *config = FcConfigReference (NULL);
|
||||
FcBool ret = FcTrue;
|
||||
time_t now;
|
||||
|
||||
if (!config)
|
||||
|
@ -238,19 +239,23 @@ FcInitBringUptoDate (void)
|
|||
* rescanInterval == 0 disables automatic up to date
|
||||
*/
|
||||
if (config->rescanInterval == 0)
|
||||
return FcTrue;
|
||||
goto bail;
|
||||
/*
|
||||
* Check no more often than rescanInterval seconds
|
||||
*/
|
||||
now = time (0);
|
||||
if (config->rescanTime + config->rescanInterval - now > 0)
|
||||
return FcTrue;
|
||||
goto bail;
|
||||
/*
|
||||
* If up to date, don't reload configuration
|
||||
*/
|
||||
if (FcConfigUptoDate (0))
|
||||
return FcTrue;
|
||||
return FcInitReinitialize ();
|
||||
goto bail;
|
||||
ret = FcInitReinitialize ();
|
||||
bail:
|
||||
FcConfigDestroy (config);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#define __fcinit__
|
||||
|
|
25
src/fclist.c
25
src/fclist.c
|
@ -491,11 +491,10 @@ FcFontSetList (FcConfig *config,
|
|||
{
|
||||
if (!FcInitBringUptoDate ())
|
||||
goto bail0;
|
||||
|
||||
config = FcConfigGetCurrent ();
|
||||
if (!config)
|
||||
goto bail0;
|
||||
}
|
||||
config = FcConfigReference (config);
|
||||
if (!config)
|
||||
goto bail0;
|
||||
FcListHashTableInit (&table);
|
||||
|
||||
if (!os)
|
||||
|
@ -558,7 +557,7 @@ FcFontSetList (FcConfig *config,
|
|||
*/
|
||||
ret = FcFontSetCreate ();
|
||||
if (!ret)
|
||||
goto bail0;
|
||||
goto bail1;
|
||||
for (i = 0; i < FC_LIST_HASH_SIZE; i++)
|
||||
while ((bucket = table.buckets[i]))
|
||||
{
|
||||
|
@ -570,6 +569,7 @@ FcFontSetList (FcConfig *config,
|
|||
|
||||
if (destroy_os)
|
||||
FcObjectSetDestroy (os);
|
||||
FcConfigDestroy (config);
|
||||
|
||||
return ret;
|
||||
|
||||
|
@ -577,6 +577,7 @@ bail2:
|
|||
FcFontSetDestroy (ret);
|
||||
bail1:
|
||||
FcListHashTableCleanup (&table);
|
||||
FcConfigDestroy (config);
|
||||
bail0:
|
||||
if (destroy_os)
|
||||
FcObjectSetDestroy (os);
|
||||
|
@ -588,24 +589,26 @@ FcFontList (FcConfig *config,
|
|||
FcPattern *p,
|
||||
FcObjectSet *os)
|
||||
{
|
||||
FcFontSet *sets[2];
|
||||
FcFontSet *sets[2], *ret;
|
||||
int nsets;
|
||||
|
||||
if (!config)
|
||||
{
|
||||
if (!FcInitBringUptoDate ())
|
||||
return 0;
|
||||
|
||||
config = FcConfigGetCurrent ();
|
||||
if (!config)
|
||||
return 0;
|
||||
}
|
||||
config = FcConfigReference (config);
|
||||
if (!config)
|
||||
return NULL;
|
||||
nsets = 0;
|
||||
if (config->fonts[FcSetSystem])
|
||||
sets[nsets++] = config->fonts[FcSetSystem];
|
||||
if (config->fonts[FcSetApplication])
|
||||
sets[nsets++] = config->fonts[FcSetApplication];
|
||||
return FcFontSetList (config, sets, nsets, p, os);
|
||||
ret = FcFontSetList (config, sets, nsets, p, os);
|
||||
FcConfigDestroy (config);
|
||||
|
||||
return ret;
|
||||
}
|
||||
#define __fclist__
|
||||
#include "fcaliastail.h"
|
||||
|
|
|
@ -845,7 +845,7 @@ FcFontSetMatch (FcConfig *config,
|
|||
FcPattern *p,
|
||||
FcResult *result)
|
||||
{
|
||||
FcPattern *best;
|
||||
FcPattern *best, *ret = NULL;
|
||||
|
||||
assert (sets != NULL);
|
||||
assert (p != NULL);
|
||||
|
@ -853,17 +853,16 @@ FcFontSetMatch (FcConfig *config,
|
|||
|
||||
*result = FcResultNoMatch;
|
||||
|
||||
config = FcConfigReference (config);
|
||||
if (!config)
|
||||
{
|
||||
config = FcConfigGetCurrent ();
|
||||
if (!config)
|
||||
return 0;
|
||||
}
|
||||
return NULL;
|
||||
best = FcFontSetMatchInternal (sets, nsets, p, result);
|
||||
if (best)
|
||||
return FcFontRenderPrepare (config, p, best);
|
||||
else
|
||||
return NULL;
|
||||
ret = FcFontRenderPrepare (config, p, best);
|
||||
|
||||
FcConfigDestroy (config);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
FcPattern *
|
||||
|
@ -873,19 +872,16 @@ FcFontMatch (FcConfig *config,
|
|||
{
|
||||
FcFontSet *sets[2];
|
||||
int nsets;
|
||||
FcPattern *best;
|
||||
FcPattern *best, *ret = NULL;
|
||||
|
||||
assert (p != NULL);
|
||||
assert (result != NULL);
|
||||
|
||||
*result = FcResultNoMatch;
|
||||
|
||||
config = FcConfigReference (config);
|
||||
if (!config)
|
||||
{
|
||||
config = FcConfigGetCurrent ();
|
||||
if (!config)
|
||||
return 0;
|
||||
}
|
||||
return NULL;
|
||||
nsets = 0;
|
||||
if (config->fonts[FcSetSystem])
|
||||
sets[nsets++] = config->fonts[FcSetSystem];
|
||||
|
@ -894,9 +890,11 @@ FcFontMatch (FcConfig *config,
|
|||
|
||||
best = FcFontSetMatchInternal (sets, nsets, p, result);
|
||||
if (best)
|
||||
return FcFontRenderPrepare (config, p, best);
|
||||
else
|
||||
return NULL;
|
||||
ret = FcFontRenderPrepare (config, p, best);
|
||||
|
||||
FcConfigDestroy (config);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
typedef struct _FcSortNode {
|
||||
|
@ -1183,7 +1181,7 @@ FcFontSort (FcConfig *config,
|
|||
FcCharSet **csp,
|
||||
FcResult *result)
|
||||
{
|
||||
FcFontSet *sets[2];
|
||||
FcFontSet *sets[2], *ret;
|
||||
int nsets;
|
||||
|
||||
assert (p != NULL);
|
||||
|
@ -1191,18 +1189,18 @@ FcFontSort (FcConfig *config,
|
|||
|
||||
*result = FcResultNoMatch;
|
||||
|
||||
config = FcConfigReference (config);
|
||||
if (!config)
|
||||
{
|
||||
config = FcConfigGetCurrent ();
|
||||
if (!config)
|
||||
return 0;
|
||||
}
|
||||
return NULL;
|
||||
nsets = 0;
|
||||
if (config->fonts[FcSetSystem])
|
||||
sets[nsets++] = config->fonts[FcSetSystem];
|
||||
if (config->fonts[FcSetApplication])
|
||||
sets[nsets++] = config->fonts[FcSetApplication];
|
||||
return FcFontSetSort (config, sets, nsets, p, trim, csp, result);
|
||||
ret = FcFontSetSort (config, sets, nsets, p, trim, csp, result);
|
||||
FcConfigDestroy (config);
|
||||
|
||||
return ret;
|
||||
}
|
||||
#define __fcmatch__
|
||||
#include "fcaliastail.h"
|
||||
|
|
|
@ -42,6 +42,11 @@ test_pthread_LDADD = $(top_builddir)/src/libfontconfig.la
|
|||
# We don't enable this test by default because it will require config and fonts
|
||||
# to meaningfully test anything, and we are not installed yet.
|
||||
#TESTS += test-pthread
|
||||
|
||||
check_PROGRAMS += test-crbug1004254
|
||||
test_crbug1004254_LDADD = $(top_builddir)/src/libfontconfig.la
|
||||
# Disabling this for the same reason as above but trying to run in run-test.sh.
|
||||
#TESTS += test-crbug1004254
|
||||
endif
|
||||
check_PROGRAMS += test-bz89617
|
||||
test_bz89617_CFLAGS = \
|
||||
|
|
|
@ -20,6 +20,8 @@
|
|||
# DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||
# TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
# PERFORMANCE OF THIS SOFTWARE.
|
||||
set -e
|
||||
|
||||
case "$OSTYPE" in
|
||||
msys ) MyPWD=`pwd -W` ;; # On Msys/MinGW, returns a MS Windows style path.
|
||||
* ) MyPWD=`pwd` ;; # On any other platforms, returns a Unix style path.
|
||||
|
@ -408,4 +410,17 @@ rm -rf $MYCACHEBASEDIR $MYCONFIG my-fonts.conf my-out my-out.expected
|
|||
|
||||
fi # if [ "x$EXEEXT" = "x" ]
|
||||
|
||||
if [ -x $BUILDTESTDIR/test-crbug1004254 ]; then
|
||||
dotest "MT-safe global config"
|
||||
prep
|
||||
curl -s -o $FONTDIR/noto.zip https://noto-website-2.storage.googleapis.com/pkgs/NotoSans-hinted.zip
|
||||
(cd $FONTDIR; unzip noto.zip)
|
||||
if [ -n ${SOURCE_DATE_EPOCH:-} ] && [ ${#SOURCE_DATE_EPOCH} -gt 0 ]; then
|
||||
touch -m -t "`date -d \"@${SOURCE_DATE_EPOCH}\" +%y%m%d%H%M.%S`" $FONTDIR
|
||||
fi
|
||||
$BUILDTESTDIR/test-crbug1004254
|
||||
else
|
||||
echo "No test-crbug1004254: skipped"
|
||||
fi
|
||||
|
||||
rm -rf $FONTDIR $CACHEFILE $CACHEDIR $BASEDIR $FONTCONFIG_FILE out
|
||||
|
|
|
@ -0,0 +1,116 @@
|
|||
/*
|
||||
* fontconfig/test/test-pthread.c
|
||||
*
|
||||
* Copyright © 2000 Keith Packard
|
||||
* Copyright © 2013 Raimund Steger
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
* documentation for any purpose is hereby granted without fee, provided that
|
||||
* the above copyright notice appear in all copies and that both that
|
||||
* copyright notice and this permission notice appear in supporting
|
||||
* documentation, and that the name of the author(s) not be used in
|
||||
* advertising or publicity pertaining to distribution of the software without
|
||||
* specific, written prior permission. The authors make no
|
||||
* representations about the suitability of this software for any purpose. It
|
||||
* is provided "as is" without express or implied warranty.
|
||||
*
|
||||
* THE AUTHOR(S) DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||
* EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <pthread.h>
|
||||
#include <fontconfig/fontconfig.h>
|
||||
|
||||
struct thr_arg_s
|
||||
{
|
||||
int thr_num;
|
||||
};
|
||||
|
||||
static void
|
||||
run_query (void)
|
||||
{
|
||||
FcPattern *pat = FcPatternCreate (), *match;
|
||||
FcResult result;
|
||||
|
||||
FcPatternAddString (pat, FC_FAMILY, "sans-serif");
|
||||
FcPatternAddBool (pat, FC_SCALABLE, FcTrue);
|
||||
FcConfigSubstitute (NULL, pat, FcMatchPattern);
|
||||
FcDefaultSubstitute (pat);
|
||||
match = FcFontMatch (NULL, pat, &result);
|
||||
if (result != FcResultMatch || !match)
|
||||
{
|
||||
fprintf (stderr, "ERROR: No matches found\n");
|
||||
}
|
||||
if (match)
|
||||
FcPatternDestroy (match);
|
||||
FcPatternDestroy (pat);
|
||||
}
|
||||
|
||||
static void
|
||||
run_reinit (void)
|
||||
{
|
||||
if (!FcInitReinitialize ())
|
||||
{
|
||||
fprintf (stderr, "ERROR: Reinitializing failed\n");
|
||||
}
|
||||
}
|
||||
|
||||
#define NTEST 3000
|
||||
|
||||
static void *
|
||||
run_test_in_thread (void *arg)
|
||||
{
|
||||
struct thr_arg_s *thr_arg = (struct thr_arg_s *) arg;
|
||||
int thread_num = thr_arg->thr_num;
|
||||
|
||||
fprintf (stderr, "Worker %d: started (round %d)\n", thread_num % 2, thread_num / 2);
|
||||
if ((thread_num % 2) == 0)
|
||||
{
|
||||
run_query ();
|
||||
}
|
||||
else
|
||||
{
|
||||
run_reinit ();
|
||||
}
|
||||
fprintf (stderr, "Worker %d: done (round %d)\n", thread_num % 2, thread_num / 2);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
pthread_t threads[NTEST];
|
||||
struct thr_arg_s thr_arg[NTEST];
|
||||
int i, j;
|
||||
|
||||
for (i = 0; i < NTEST; i++)
|
||||
{
|
||||
int result;
|
||||
|
||||
fprintf (stderr, "Thread %d (worker %d round %d): creating\n", i, i % 2, i / 2);
|
||||
thr_arg[i].thr_num = i;
|
||||
result = pthread_create (&threads[i], NULL, run_test_in_thread,
|
||||
(void *) &thr_arg[i]);
|
||||
if (result != 0)
|
||||
{
|
||||
fprintf (stderr, "Cannot create thread %d\n", i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (j = 0; j < i; j++)
|
||||
{
|
||||
pthread_join(threads[j], NULL);
|
||||
fprintf (stderr, "Joined thread %d\n", j);
|
||||
}
|
||||
FcFini ();
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue