Make refcounts, patterns, charsets, strings, and FcLang thread-safe
This commit is contained in:
parent
814871b2aa
commit
64af9e1917
|
@ -63,7 +63,7 @@ static inline void HBMemoryBarrier (void) {
|
|||
}
|
||||
#endif
|
||||
|
||||
typedef long fc_atomic_int_t;
|
||||
typedef int fc_atomic_int_t;
|
||||
#define fc_atomic_int_add(AI, V) InterlockedExchangeAdd (&(AI), (V))
|
||||
|
||||
#define fc_atomic_ptr_get(P) (HBMemoryBarrier (), (void *) *(P))
|
||||
|
@ -74,7 +74,7 @@ typedef long fc_atomic_int_t;
|
|||
|
||||
#include <libkern/OSAtomic.h>
|
||||
|
||||
typedef int32_t fc_atomic_int_t;
|
||||
typedef int fc_atomic_int_t;
|
||||
#define fc_atomic_int_add(AI, V) (OSAtomicAdd32Barrier ((V), &(AI)) - (V))
|
||||
|
||||
#define fc_atomic_ptr_get(P) (OSMemoryBarrier (), (void *) *(P))
|
||||
|
@ -111,13 +111,13 @@ typedef int fc_atomic_int_t;
|
|||
#endif
|
||||
|
||||
/* reference count */
|
||||
#define FC_REF_CONSTANT ((fc_atomic_int_t) -1)
|
||||
#define FC_REF_CONSTANT_INIT {FC_REF_CONSTANT}
|
||||
#define FC_REF_CONSTANT_VALUE ((fc_atomic_int_t) -1)
|
||||
#define FC_REF_CONSTANT {FC_REF_CONSTANT_VALUE}
|
||||
typedef struct _FcRef { fc_atomic_int_t count; } FcRef;
|
||||
static inline void FcRefInit (FcRef *r, int v) { r->count = v; }
|
||||
static inline int FcRefInc (FcRef *r) { return fc_atomic_int_add (r->count, +1); }
|
||||
static inline int FcRefDec (FcRef *r) { return fc_atomic_int_add (r->count, -1); }
|
||||
static inline void FcRefFinish (FcRef *r) { r->count = FC_REF_CONSTANT; }
|
||||
static inline FcBool FcRefIsConst (FcRef *r) { return r->count == FC_REF_CONSTANT; }
|
||||
static inline void FcRefInit (FcRef *r, int v) { r->count = v; }
|
||||
static inline int FcRefInc (FcRef *r) { return fc_atomic_int_add (r->count, +1); }
|
||||
static inline int FcRefDec (FcRef *r) { return fc_atomic_int_add (r->count, -1); }
|
||||
static inline void FcRefSetConst (FcRef *r) { r->count = FC_REF_CONSTANT_VALUE; }
|
||||
static inline FcBool FcRefIsConst (const FcRef *r) { return r->count == FC_REF_CONSTANT_VALUE; }
|
||||
|
||||
#endif /* _FCATOMIC_H_ */
|
||||
|
|
29
src/fccfg.c
29
src/fccfg.c
|
@ -94,7 +94,7 @@ FcConfigCreate (void)
|
|||
|
||||
config->expr_pool = NULL;
|
||||
|
||||
config->ref = 1;
|
||||
FcRefInit (&config->ref, 1);
|
||||
|
||||
return config;
|
||||
|
||||
|
@ -221,7 +221,7 @@ FcConfigReference (FcConfig *config)
|
|||
return 0;
|
||||
}
|
||||
|
||||
config->ref++;
|
||||
FcRefInc (&config->ref);
|
||||
|
||||
return config;
|
||||
}
|
||||
|
@ -232,7 +232,7 @@ FcConfigDestroy (FcConfig *config)
|
|||
FcSetName set;
|
||||
FcExprPage *page;
|
||||
|
||||
if (--config->ref > 0)
|
||||
if (FcRefDec (&config->ref) != 1)
|
||||
return;
|
||||
|
||||
if (config == _fcConfig)
|
||||
|
@ -662,7 +662,7 @@ typedef struct _FcSubState {
|
|||
} FcSubState;
|
||||
|
||||
static FcValue
|
||||
FcConfigPromote (FcValue v, FcValue u)
|
||||
FcConfigPromote (FcValue v, FcValue u, FcValuePromotionBuffer *buf)
|
||||
{
|
||||
if (v.type == FcTypeInteger)
|
||||
{
|
||||
|
@ -674,9 +674,9 @@ FcConfigPromote (FcValue v, FcValue u)
|
|||
v.u.m = &FcIdentityMatrix;
|
||||
v.type = FcTypeMatrix;
|
||||
}
|
||||
else if (v.type == FcTypeString && u.type == FcTypeLangSet)
|
||||
else if (buf && v.type == FcTypeString && u.type == FcTypeLangSet)
|
||||
{
|
||||
v.u.l = FcLangSetPromote (v.u.s);
|
||||
v.u.l = FcLangSetPromote (v.u.s, buf);
|
||||
v.type = FcTypeLangSet;
|
||||
}
|
||||
return v;
|
||||
|
@ -692,9 +692,10 @@ FcConfigCompareValue (const FcValue *left_o,
|
|||
FcBool ret = FcFalse;
|
||||
FcOp op = FC_OP_GET_OP (op_);
|
||||
int flags = FC_OP_GET_FLAGS (op_);
|
||||
FcValuePromotionBuffer buf1, buf2;
|
||||
|
||||
left = FcConfigPromote (left, right);
|
||||
right = FcConfigPromote (right, left);
|
||||
left = FcConfigPromote (left, right, &buf1);
|
||||
right = FcConfigPromote (right, left, &buf2);
|
||||
if (left.type == right.type)
|
||||
{
|
||||
switch (left.type) {
|
||||
|
@ -893,10 +894,10 @@ FcConfigEvaluate (FcPattern *p, FcPattern *p_pat, FcMatchKind kind, FcExpr *e)
|
|||
FcMatrix m;
|
||||
FcValue xx, xy, yx, yy;
|
||||
v.type = FcTypeMatrix;
|
||||
xx = FcConfigPromote (FcConfigEvaluate (p, p_pat, kind, e->u.mexpr->xx), v);
|
||||
xy = FcConfigPromote (FcConfigEvaluate (p, p_pat, kind, e->u.mexpr->xy), v);
|
||||
yx = FcConfigPromote (FcConfigEvaluate (p, p_pat, kind, e->u.mexpr->yx), v);
|
||||
yy = FcConfigPromote (FcConfigEvaluate (p, p_pat, kind, e->u.mexpr->yy), v);
|
||||
xx = FcConfigPromote (FcConfigEvaluate (p, p_pat, kind, e->u.mexpr->xx), v, NULL);
|
||||
xy = FcConfigPromote (FcConfigEvaluate (p, p_pat, kind, e->u.mexpr->xy), v, NULL);
|
||||
yx = FcConfigPromote (FcConfigEvaluate (p, p_pat, kind, e->u.mexpr->yx), v, NULL);
|
||||
yy = FcConfigPromote (FcConfigEvaluate (p, p_pat, kind, e->u.mexpr->yy), v, NULL);
|
||||
if (xx.type == FcTypeDouble && xy.type == FcTypeDouble &&
|
||||
yx.type == FcTypeDouble && yy.type == FcTypeDouble)
|
||||
{
|
||||
|
@ -987,8 +988,8 @@ FcConfigEvaluate (FcPattern *p, FcPattern *p_pat, FcMatchKind kind, FcExpr *e)
|
|||
case FcOpDivide:
|
||||
vl = FcConfigEvaluate (p, p_pat, kind, e->u.tree.left);
|
||||
vr = FcConfigEvaluate (p, p_pat, kind, e->u.tree.right);
|
||||
vl = FcConfigPromote (vl, vr);
|
||||
vr = FcConfigPromote (vr, vl);
|
||||
vl = FcConfigPromote (vl, vr, NULL);
|
||||
vr = FcConfigPromote (vr, vl, NULL);
|
||||
if (vl.type == vr.type)
|
||||
{
|
||||
switch ((int) vl.type) {
|
||||
|
|
|
@ -35,7 +35,7 @@ FcCharSetCreate (void)
|
|||
fcs = (FcCharSet *) malloc (sizeof (FcCharSet));
|
||||
if (!fcs)
|
||||
return 0;
|
||||
fcs->ref = 1;
|
||||
FcRefInit (&fcs->ref, 1);
|
||||
fcs->num = 0;
|
||||
fcs->leaves_offset = 0;
|
||||
fcs->numbers_offset = 0;
|
||||
|
@ -55,12 +55,12 @@ FcCharSetDestroy (FcCharSet *fcs)
|
|||
|
||||
if (fcs)
|
||||
{
|
||||
if (fcs->ref == FC_REF_CONSTANT)
|
||||
if (FcRefIsConst (&fcs->ref))
|
||||
{
|
||||
FcCacheObjectDereference (fcs);
|
||||
return;
|
||||
}
|
||||
if (--fcs->ref > 0)
|
||||
if (FcRefDec (&fcs->ref) != 1)
|
||||
return;
|
||||
for (i = 0; i < fcs->num; i++)
|
||||
free (FcCharSetLeaf (fcs, i));
|
||||
|
@ -237,7 +237,7 @@ FcCharSetAddChar (FcCharSet *fcs, FcChar32 ucs4)
|
|||
FcCharLeaf *leaf;
|
||||
FcChar32 *b;
|
||||
|
||||
if (fcs == NULL || fcs->ref == FC_REF_CONSTANT)
|
||||
if (fcs == NULL || FcRefIsConst (&fcs->ref))
|
||||
return FcFalse;
|
||||
leaf = FcCharSetFindLeafCreate (fcs, ucs4);
|
||||
if (!leaf)
|
||||
|
@ -253,7 +253,7 @@ FcCharSetDelChar (FcCharSet *fcs, FcChar32 ucs4)
|
|||
FcCharLeaf *leaf;
|
||||
FcChar32 *b;
|
||||
|
||||
if (fcs == NULL || fcs->ref == FC_REF_CONSTANT)
|
||||
if (fcs == NULL || FcRefIsConst (&fcs->ref))
|
||||
return FcFalse;
|
||||
leaf = FcCharSetFindLeaf (fcs, ucs4);
|
||||
if (!leaf)
|
||||
|
@ -329,8 +329,8 @@ FcCharSetCopy (FcCharSet *src)
|
|||
{
|
||||
if (src)
|
||||
{
|
||||
if (src->ref != FC_REF_CONSTANT)
|
||||
src->ref++;
|
||||
if (!FcRefIsConst (&src->ref))
|
||||
FcRefInc (&src->ref);
|
||||
else
|
||||
FcCacheObjectReference (src);
|
||||
}
|
||||
|
@ -488,7 +488,7 @@ FcCharSetMerge (FcCharSet *a, const FcCharSet *b, FcBool *changed)
|
|||
if (!a || !b)
|
||||
return FcFalse;
|
||||
|
||||
if (a->ref == FC_REF_CONSTANT) {
|
||||
if (FcRefIsConst (&a->ref)) {
|
||||
if (changed)
|
||||
*changed = FcFalse;
|
||||
return FcFalse;
|
||||
|
@ -1204,7 +1204,7 @@ FcCharSetFreezeBase (FcCharSetFreezer *freezer, FcCharSet *fcs)
|
|||
|
||||
freezer->charsets_allocated++;
|
||||
|
||||
ent->set.ref = FC_REF_CONSTANT;
|
||||
FcRefSetConst (&ent->set.ref);
|
||||
ent->set.num = fcs->num;
|
||||
if (fcs->num)
|
||||
{
|
||||
|
@ -1338,7 +1338,7 @@ FcCharSetSerializeAlloc (FcSerialize *serialize, const FcCharSet *cs)
|
|||
FcChar16 *numbers;
|
||||
int i;
|
||||
|
||||
if (cs->ref != FC_REF_CONSTANT)
|
||||
if (!FcRefIsConst (&cs->ref))
|
||||
{
|
||||
if (!serialize->cs_freezer)
|
||||
{
|
||||
|
@ -1377,7 +1377,7 @@ FcCharSetSerialize(FcSerialize *serialize, const FcCharSet *cs)
|
|||
FcCharLeaf *leaf, *leaf_serialized;
|
||||
int i;
|
||||
|
||||
if (cs->ref != FC_REF_CONSTANT && serialize->cs_freezer)
|
||||
if (!FcRefIsConst (&cs->ref) && serialize->cs_freezer)
|
||||
{
|
||||
cs = FcCharSetFindFrozen (serialize->cs_freezer, cs);
|
||||
if (!cs)
|
||||
|
@ -1388,7 +1388,7 @@ FcCharSetSerialize(FcSerialize *serialize, const FcCharSet *cs)
|
|||
if (!cs_serialized)
|
||||
return NULL;
|
||||
|
||||
cs_serialized->ref = FC_REF_CONSTANT;
|
||||
FcRefSetConst (&cs_serialized->ref);
|
||||
cs_serialized->num = cs->num;
|
||||
|
||||
if (cs->num)
|
||||
|
|
|
@ -170,7 +170,7 @@ FcDefaultSubstitute (FcPattern *pattern)
|
|||
FcPatternObjectAdd (pattern, FC_FULLNAMELANG_OBJECT, namelang, FcTrue);
|
||||
FcPatternObjectAddWithBinding (pattern, FC_FULLNAMELANG_OBJECT, v2, FcValueBindingWeak, FcTrue);
|
||||
}
|
||||
FcSharedStrFree (v2.u.s);
|
||||
FcSharedStrFree ((char *) v2.u.s);
|
||||
}
|
||||
#define __fcdefault__
|
||||
#include "fcaliastail.h"
|
||||
|
|
26
src/fcint.h
26
src/fcint.h
|
@ -35,6 +35,7 @@
|
|||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <stddef.h>
|
||||
|
@ -108,6 +109,8 @@ extern pfnSHGetFolderPathA pSHGetFolderPathA;
|
|||
#define FcPrivate
|
||||
#endif
|
||||
|
||||
FC_ASSERT_STATIC (sizeof (FcRef) == sizeof (int));
|
||||
|
||||
typedef enum _FcValueBinding {
|
||||
FcValueBindingWeak, FcValueBindingStrong, FcValueBindingSame
|
||||
} FcValueBinding;
|
||||
|
@ -188,7 +191,7 @@ struct _FcPattern {
|
|||
int num;
|
||||
int size;
|
||||
intptr_t elts_offset;
|
||||
int ref;
|
||||
FcRef ref;
|
||||
};
|
||||
|
||||
#define FcPatternElts(p) FcOffsetMember(p,elts_offset,FcPatternElt)
|
||||
|
@ -296,7 +299,7 @@ typedef struct _FcCharLeaf {
|
|||
} FcCharLeaf;
|
||||
|
||||
struct _FcCharSet {
|
||||
int ref; /* reference count */
|
||||
FcRef ref; /* reference count */
|
||||
int num; /* size of leaves and numbers arrays */
|
||||
intptr_t leaves_offset;
|
||||
intptr_t numbers_offset;
|
||||
|
@ -309,7 +312,7 @@ struct _FcCharSet {
|
|||
#define FcCharSetNumbers(c) FcOffsetMember(c,numbers_offset,FcChar16)
|
||||
|
||||
struct _FcStrSet {
|
||||
int ref; /* reference count */
|
||||
FcRef ref; /* reference count */
|
||||
int num;
|
||||
int size;
|
||||
FcChar8 **strs;
|
||||
|
@ -497,7 +500,7 @@ struct _FcConfig {
|
|||
time_t rescanTime; /* last time information was scanned */
|
||||
int rescanInterval; /* interval between scans */
|
||||
|
||||
int ref; /* reference count */
|
||||
FcRef ref; /* reference count */
|
||||
|
||||
FcExprPage *expr_pool; /* pool of FcExpr's */
|
||||
};
|
||||
|
@ -525,6 +528,17 @@ struct _FcStatFS {
|
|||
FcBool is_mtime_broken;
|
||||
};
|
||||
|
||||
typedef struct _FcValuePromotionBuffer FcValuePromotionBuffer;
|
||||
|
||||
struct _FcValuePromotionBuffer {
|
||||
union {
|
||||
double d;
|
||||
int i;
|
||||
long l;
|
||||
char c[256]; /* Enlarge as needed */
|
||||
} u;
|
||||
};
|
||||
|
||||
/* fcblanks.c */
|
||||
|
||||
/* fccache.c */
|
||||
|
@ -798,7 +812,7 @@ FcPrivate FcLangResult
|
|||
FcLangCompare (const FcChar8 *s1, const FcChar8 *s2);
|
||||
|
||||
FcPrivate FcLangSet *
|
||||
FcLangSetPromote (const FcChar8 *lang);
|
||||
FcLangSetPromote (const FcChar8 *lang, FcValuePromotionBuffer *buf);
|
||||
|
||||
FcPrivate FcLangSet *
|
||||
FcNameParseLangSet (const FcChar8 *string);
|
||||
|
@ -952,7 +966,7 @@ FcPrivate const FcChar8 *
|
|||
FcSharedStr (const FcChar8 *name);
|
||||
|
||||
FcPrivate FcBool
|
||||
FcSharedStrFree (const FcChar8 *name);
|
||||
FcSharedStrFree (FcChar8 *name);
|
||||
|
||||
FcPrivate FcChar32
|
||||
FcStringHash (const FcChar8 *s);
|
||||
|
|
41
src/fclang.c
41
src/fclang.c
|
@ -22,10 +22,11 @@
|
|||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include "fcint.h"
|
||||
#include "fcftint.h"
|
||||
|
||||
/* Objects MT-safe for readonly access. */
|
||||
|
||||
typedef struct {
|
||||
const FcChar8 lang[8];
|
||||
const FcCharSet charset;
|
||||
|
@ -702,34 +703,38 @@ FcLangSetCompare (const FcLangSet *lsa, const FcLangSet *lsb)
|
|||
|
||||
/*
|
||||
* Used in computing values -- mustn't allocate any storage
|
||||
* XXX Not thread-safe
|
||||
*/
|
||||
FcLangSet *
|
||||
FcLangSetPromote (const FcChar8 *lang)
|
||||
FcLangSetPromote (const FcChar8 *lang, FcValuePromotionBuffer *vbuf)
|
||||
{
|
||||
static FcLangSet ls;
|
||||
static FcStrSet strs;
|
||||
static FcChar8 *str;
|
||||
int id;
|
||||
int id;
|
||||
typedef struct {
|
||||
FcLangSet ls;
|
||||
FcStrSet strs;
|
||||
FcChar8 *str;
|
||||
} FcLangSetPromotionBuffer;
|
||||
FcLangSetPromotionBuffer *buf = (FcLangSetPromotionBuffer *) vbuf;
|
||||
|
||||
memset (ls.map, '\0', sizeof (ls.map));
|
||||
ls.map_size = NUM_LANG_SET_MAP;
|
||||
ls.extra = 0;
|
||||
FC_ASSERT_STATIC (sizeof (FcLangSetPromotionBuffer) <= sizeof (FcValuePromotionBuffer));
|
||||
|
||||
memset (buf->ls.map, '\0', sizeof (buf->ls.map));
|
||||
buf->ls.map_size = NUM_LANG_SET_MAP;
|
||||
buf->ls.extra = 0;
|
||||
id = FcLangSetIndex (lang);
|
||||
if (id > 0)
|
||||
{
|
||||
FcLangSetBitSet (&ls, id);
|
||||
FcLangSetBitSet (&buf->ls, id);
|
||||
}
|
||||
else
|
||||
{
|
||||
ls.extra = &strs;
|
||||
strs.num = 1;
|
||||
strs.size = 1;
|
||||
strs.strs = &str;
|
||||
strs.ref = 1;
|
||||
str = (FcChar8 *) lang;
|
||||
buf->ls.extra = &buf->strs;
|
||||
buf->strs.num = 1;
|
||||
buf->strs.size = 1;
|
||||
buf->strs.strs = &buf->str;
|
||||
FcRefInit (&buf->strs.ref, 1);
|
||||
buf->str = (FcChar8 *) lang;
|
||||
}
|
||||
return &ls;
|
||||
return &buf->ls;
|
||||
}
|
||||
|
||||
FcChar32
|
||||
|
|
|
@ -23,10 +23,6 @@
|
|||
*/
|
||||
|
||||
#include "fcint.h"
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <stdio.h>
|
||||
|
||||
static double
|
||||
FcCompareNumber (FcValue *value1, FcValue *value2)
|
||||
|
|
|
@ -36,6 +36,8 @@
|
|||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#define FC_STMT_START do
|
||||
#define FC_STMT_END while (0)
|
||||
|
||||
/* mutex */
|
||||
|
||||
|
|
25
src/fcpat.c
25
src/fcpat.c
|
@ -22,9 +22,8 @@
|
|||
|
||||
#include "fcint.h"
|
||||
#include "fcftint.h"
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
/* Objects MT-safe for readonly access. */
|
||||
|
||||
FcPattern *
|
||||
FcPatternCreate (void)
|
||||
|
@ -37,7 +36,7 @@ FcPatternCreate (void)
|
|||
p->num = 0;
|
||||
p->size = 0;
|
||||
p->elts_offset = FcPtrToOffset (p, NULL);
|
||||
p->ref = 1;
|
||||
FcRefInit (&p->ref, 1);
|
||||
return p;
|
||||
}
|
||||
|
||||
|
@ -362,13 +361,13 @@ FcPatternDestroy (FcPattern *p)
|
|||
if (!p)
|
||||
return;
|
||||
|
||||
if (p->ref == FC_REF_CONSTANT)
|
||||
if (FcRefIsConst (&p->ref))
|
||||
{
|
||||
FcCacheObjectDereference (p);
|
||||
return;
|
||||
}
|
||||
|
||||
if (--p->ref > 0)
|
||||
if (FcRefDec (&p->ref) != 1)
|
||||
return;
|
||||
|
||||
elts = FcPatternElts (p);
|
||||
|
@ -546,7 +545,7 @@ FcPatternObjectListAdd (FcPattern *p,
|
|||
FcPatternElt *e;
|
||||
FcValueListPtr l, *prev;
|
||||
|
||||
if (p->ref == FC_REF_CONSTANT)
|
||||
if (FcRefIsConst (&p->ref))
|
||||
goto bail0;
|
||||
|
||||
/*
|
||||
|
@ -598,7 +597,7 @@ FcPatternObjectAddWithBinding (FcPattern *p,
|
|||
FcPatternElt *e;
|
||||
FcValueListPtr new, *prev;
|
||||
|
||||
if (p->ref == FC_REF_CONSTANT)
|
||||
if (FcRefIsConst (&p->ref))
|
||||
goto bail0;
|
||||
|
||||
new = FcValueListCreate ();
|
||||
|
@ -1060,8 +1059,8 @@ bail0:
|
|||
void
|
||||
FcPatternReference (FcPattern *p)
|
||||
{
|
||||
if (p->ref != FC_REF_CONSTANT)
|
||||
p->ref++;
|
||||
if (!FcRefIsConst (&p->ref))
|
||||
FcRefInc (&p->ref);
|
||||
else
|
||||
FcCacheObjectReference (p);
|
||||
}
|
||||
|
@ -1153,7 +1152,7 @@ bail0:
|
|||
* significant by any means. */
|
||||
|
||||
FcBool
|
||||
FcSharedStrFree (const FcChar8 *name)
|
||||
FcSharedStrFree (FcChar8 *name)
|
||||
{
|
||||
free (name);
|
||||
return FcTrue;
|
||||
|
@ -1162,7 +1161,7 @@ FcSharedStrFree (const FcChar8 *name)
|
|||
const FcChar8 *
|
||||
FcSharedStr (const FcChar8 *name)
|
||||
{
|
||||
return strdup (name);
|
||||
return strdup ((const char *) name);
|
||||
}
|
||||
|
||||
FcBool
|
||||
|
@ -1195,7 +1194,7 @@ FcPatternSerialize (FcSerialize *serialize, const FcPattern *pat)
|
|||
return NULL;
|
||||
*pat_serialized = *pat;
|
||||
pat_serialized->size = pat->num;
|
||||
pat_serialized->ref = FC_REF_CONSTANT;
|
||||
FcRefSetConst (&pat_serialized->ref);
|
||||
|
||||
elts_serialized = FcSerializePtr (serialize, elts);
|
||||
if (!elts_serialized)
|
||||
|
|
24
src/fcstr.c
24
src/fcstr.c
|
@ -33,6 +33,8 @@
|
|||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
/* Objects MT-safe for readonly access. */
|
||||
|
||||
FcChar8 *
|
||||
FcStrCopy (const FcChar8 *s)
|
||||
{
|
||||
|
@ -1078,7 +1080,7 @@ FcStrSetCreate (void)
|
|||
FcStrSet *set = malloc (sizeof (FcStrSet));
|
||||
if (!set)
|
||||
return 0;
|
||||
set->ref = 1;
|
||||
FcRefInit (&set->ref, 1);
|
||||
set->num = 0;
|
||||
set->size = 0;
|
||||
set->strs = 0;
|
||||
|
@ -1230,16 +1232,16 @@ FcStrSetDel (FcStrSet *set, const FcChar8 *s)
|
|||
void
|
||||
FcStrSetDestroy (FcStrSet *set)
|
||||
{
|
||||
if (--set->ref == 0)
|
||||
{
|
||||
int i;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < set->num; i++)
|
||||
FcStrFree (set->strs[i]);
|
||||
if (set->strs)
|
||||
free (set->strs);
|
||||
free (set);
|
||||
}
|
||||
if (FcRefDec (&set->ref) != 1)
|
||||
return;
|
||||
|
||||
for (i = 0; i < set->num; i++)
|
||||
FcStrFree (set->strs[i]);
|
||||
if (set->strs)
|
||||
free (set->strs);
|
||||
free (set);
|
||||
}
|
||||
|
||||
FcStrList *
|
||||
|
@ -1251,7 +1253,7 @@ FcStrListCreate (FcStrSet *set)
|
|||
if (!list)
|
||||
return 0;
|
||||
list->set = set;
|
||||
set->ref++;
|
||||
FcRefInc (&set->ref);
|
||||
list->n = 0;
|
||||
return list;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue