Make default-FcConfig threadsafe
This commit is contained in:
parent
e53f5da54f
commit
0552f26016
60
src/fccfg.c
60
src/fccfg.c
|
@ -22,6 +22,8 @@
|
||||||
* PERFORMANCE OF THIS SOFTWARE.
|
* PERFORMANCE OF THIS SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/* Objects MT-safe for readonly access. */
|
||||||
|
|
||||||
#include "fcint.h"
|
#include "fcint.h"
|
||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
@ -36,27 +38,38 @@
|
||||||
#define R_OK 4
|
#define R_OK 4
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static FcConfig *_fcConfig;
|
static FcConfig *_fcConfig; /* MT-safe */
|
||||||
|
|
||||||
|
static FcConfig *
|
||||||
|
FcConfigEnsure (void)
|
||||||
|
{
|
||||||
|
FcConfig *config;
|
||||||
|
retry:
|
||||||
|
config = fc_atomic_ptr_get (&_fcConfig);
|
||||||
|
if (!config)
|
||||||
|
{
|
||||||
|
config = FcInitLoadConfigAndFonts ();
|
||||||
|
|
||||||
|
if (!fc_atomic_ptr_cmpexch (&_fcConfig, NULL, config)) {
|
||||||
|
FcConfigDestroy (config);
|
||||||
|
goto retry;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return config;
|
||||||
|
}
|
||||||
|
|
||||||
FcBool
|
FcBool
|
||||||
FcConfigInit (void)
|
FcConfigInit (void)
|
||||||
{
|
{
|
||||||
FcConfig *config;
|
return FcConfigEnsure () ? FcTrue : FcFalse;
|
||||||
|
|
||||||
if (_fcConfig)
|
|
||||||
return FcTrue;
|
|
||||||
config = FcInitLoadConfigAndFonts ();
|
|
||||||
if (!config)
|
|
||||||
return FcFalse;
|
|
||||||
FcConfigSetCurrent (config);
|
|
||||||
return FcTrue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
FcConfigFini (void)
|
FcConfigFini (void)
|
||||||
{
|
{
|
||||||
if (_fcConfig)
|
FcConfig *cfg = fc_atomic_ptr_get (&_fcConfig);
|
||||||
FcConfigDestroy (_fcConfig);
|
if (cfg && fc_atomic_ptr_cmpexch (&_fcConfig, cfg, NULL))
|
||||||
|
FcConfigDestroy (cfg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -257,8 +270,7 @@ FcConfigDestroy (FcConfig *config)
|
||||||
if (FcRefDec (&config->ref) != 1)
|
if (FcRefDec (&config->ref) != 1)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (config == _fcConfig)
|
fc_atomic_ptr_cmpexch (&_fcConfig, config, NULL);
|
||||||
_fcConfig = 0;
|
|
||||||
|
|
||||||
FcStrSetDestroy (config->configDirs);
|
FcStrSetDestroy (config->configDirs);
|
||||||
FcStrSetDestroy (config->fontDirs);
|
FcStrSetDestroy (config->fontDirs);
|
||||||
|
@ -411,25 +423,31 @@ FcConfigBuildFonts (FcConfig *config)
|
||||||
FcBool
|
FcBool
|
||||||
FcConfigSetCurrent (FcConfig *config)
|
FcConfigSetCurrent (FcConfig *config)
|
||||||
{
|
{
|
||||||
if (config == _fcConfig)
|
FcConfig *cfg;
|
||||||
|
|
||||||
|
retry:
|
||||||
|
cfg = fc_atomic_ptr_get (&_fcConfig);
|
||||||
|
|
||||||
|
if (config == cfg)
|
||||||
return FcTrue;
|
return FcTrue;
|
||||||
|
|
||||||
if (!config->fonts[FcSetSystem])
|
if (!config->fonts[FcSetSystem])
|
||||||
if (!FcConfigBuildFonts (config))
|
if (!FcConfigBuildFonts (config))
|
||||||
return FcFalse;
|
return FcFalse;
|
||||||
|
|
||||||
if (_fcConfig)
|
if (!fc_atomic_ptr_cmpexch (&_fcConfig, cfg, config))
|
||||||
FcConfigDestroy (_fcConfig);
|
goto retry;
|
||||||
_fcConfig = config;
|
|
||||||
|
if (cfg)
|
||||||
|
FcConfigDestroy (cfg);
|
||||||
|
|
||||||
return FcTrue;
|
return FcTrue;
|
||||||
}
|
}
|
||||||
|
|
||||||
FcConfig *
|
FcConfig *
|
||||||
FcConfigGetCurrent (void)
|
FcConfigGetCurrent (void)
|
||||||
{
|
{
|
||||||
if (!_fcConfig)
|
return FcConfigEnsure ();
|
||||||
FcConfigInit ();
|
|
||||||
return _fcConfig;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
FcBool
|
FcBool
|
||||||
|
|
|
@ -119,7 +119,6 @@ FcDefaultFini (void)
|
||||||
if (langs && fc_atomic_ptr_cmpexch (&default_langs, langs, NULL)) {
|
if (langs && fc_atomic_ptr_cmpexch (&default_langs, langs, NULL)) {
|
||||||
FcRefInit (&langs->ref, 1);
|
FcRefInit (&langs->ref, 1);
|
||||||
FcStrSetDestroy (langs);
|
FcStrSetDestroy (langs);
|
||||||
langs = NULL;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -212,7 +211,7 @@ FcDefaultSubstitute (FcPattern *pattern)
|
||||||
FcPatternObjectAdd (pattern, FC_FULLNAMELANG_OBJECT, namelang, FcTrue);
|
FcPatternObjectAdd (pattern, FC_FULLNAMELANG_OBJECT, namelang, FcTrue);
|
||||||
FcPatternObjectAddWithBinding (pattern, FC_FULLNAMELANG_OBJECT, v2, FcValueBindingWeak, FcTrue);
|
FcPatternObjectAddWithBinding (pattern, FC_FULLNAMELANG_OBJECT, v2, FcValueBindingWeak, FcTrue);
|
||||||
}
|
}
|
||||||
FcSharedStrFree ((char *) v2.u.s);
|
FcSharedStrFree ((FcChar8 *) v2.u.s);
|
||||||
}
|
}
|
||||||
#define __fcdefault__
|
#define __fcdefault__
|
||||||
#include "fcaliastail.h"
|
#include "fcaliastail.h"
|
||||||
|
|
Loading…
Reference in New Issue