From: Behdad Esfahbod Date: Sun, 7 Oct 2012 21:02:50 +0000 (-0400) Subject: Make default-FcConfig threadsafe X-Git-Tag: 2.10.91~42 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=0552f26016865b8a76819cf342fa0cf13afdc5e8;p=platform%2Fupstream%2Ffontconfig.git Make default-FcConfig threadsafe --- diff --git a/src/fccfg.c b/src/fccfg.c index 1ac7c43..3245ede 100644 --- a/src/fccfg.c +++ b/src/fccfg.c @@ -22,6 +22,8 @@ * PERFORMANCE OF THIS SOFTWARE. */ +/* Objects MT-safe for readonly access. */ + #include "fcint.h" #include #include @@ -36,27 +38,38 @@ #define R_OK 4 #endif -static FcConfig *_fcConfig; +static FcConfig *_fcConfig; /* MT-safe */ -FcBool -FcConfigInit (void) +static FcConfig * +FcConfigEnsure (void) { FcConfig *config; - - if (_fcConfig) - return FcTrue; - config = FcInitLoadConfigAndFonts (); +retry: + config = fc_atomic_ptr_get (&_fcConfig); if (!config) - return FcFalse; - FcConfigSetCurrent (config); - return FcTrue; + { + config = FcInitLoadConfigAndFonts (); + + if (!fc_atomic_ptr_cmpexch (&_fcConfig, NULL, config)) { + FcConfigDestroy (config); + goto retry; + } + } + return config; +} + +FcBool +FcConfigInit (void) +{ + 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 diff --git a/src/fcdefault.c b/src/fcdefault.c index 2f13659..0069db2 100644 --- a/src/fcdefault.c +++ b/src/fcdefault.c @@ -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"