Make default-FcConfig threadsafe

This commit is contained in:
Behdad Esfahbod 2012-10-07 17:02:50 -04:00
parent e53f5da54f
commit 0552f26016
2 changed files with 40 additions and 23 deletions

View File

@ -22,6 +22,8 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* Objects MT-safe for readonly access. */
#include "fcint.h"
#include <dirent.h>
#include <sys/types.h>
@ -36,27 +38,38 @@
#define R_OK 4
#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
FcConfigInit (void)
{
FcConfig *config;
if (_fcConfig)
return FcTrue;
config = FcInitLoadConfigAndFonts ();
if (!config)
return FcFalse;
FcConfigSetCurrent (config);
return FcTrue;
return FcConfigEnsure () ? FcTrue : FcFalse;
}
void
FcConfigFini (void)
{
if (_fcConfig)
FcConfigDestroy (_fcConfig);
FcConfig *cfg = fc_atomic_ptr_get (&_fcConfig);
if (cfg && fc_atomic_ptr_cmpexch (&_fcConfig, cfg, NULL))
FcConfigDestroy (cfg);
}
@ -257,8 +270,7 @@ FcConfigDestroy (FcConfig *config)
if (FcRefDec (&config->ref) != 1)
return;
if (config == _fcConfig)
_fcConfig = 0;
fc_atomic_ptr_cmpexch (&_fcConfig, config, NULL);
FcStrSetDestroy (config->configDirs);
FcStrSetDestroy (config->fontDirs);
@ -411,25 +423,31 @@ FcConfigBuildFonts (FcConfig *config)
FcBool
FcConfigSetCurrent (FcConfig *config)
{
if (config == _fcConfig)
FcConfig *cfg;
retry:
cfg = fc_atomic_ptr_get (&_fcConfig);
if (config == cfg)
return FcTrue;
if (!config->fonts[FcSetSystem])
if (!FcConfigBuildFonts (config))
return FcFalse;
if (_fcConfig)
FcConfigDestroy (_fcConfig);
_fcConfig = config;
if (!fc_atomic_ptr_cmpexch (&_fcConfig, cfg, config))
goto retry;
if (cfg)
FcConfigDestroy (cfg);
return FcTrue;
}
FcConfig *
FcConfigGetCurrent (void)
{
if (!_fcConfig)
FcConfigInit ();
return _fcConfig;
return FcConfigEnsure ();
}
FcBool

View File

@ -119,7 +119,6 @@ FcDefaultFini (void)
if (langs && fc_atomic_ptr_cmpexch (&default_langs, langs, NULL)) {
FcRefInit (&langs->ref, 1);
FcStrSetDestroy (langs);
langs = NULL;
}
}
@ -212,7 +211,7 @@ FcDefaultSubstitute (FcPattern *pattern)
FcPatternObjectAdd (pattern, FC_FULLNAMELANG_OBJECT, namelang, FcTrue);
FcPatternObjectAddWithBinding (pattern, FC_FULLNAMELANG_OBJECT, v2, FcValueBindingWeak, FcTrue);
}
FcSharedStrFree ((char *) v2.u.s);
FcSharedStrFree ((FcChar8 *) v2.u.s);
}
#define __fcdefault__
#include "fcaliastail.h"