}
#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))
#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))
#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_ */
config->expr_pool = NULL;
- config->ref = 1;
+ FcRefInit (&config->ref, 1);
return config;
return 0;
}
- config->ref++;
+ FcRefInc (&config->ref);
return config;
}
FcSetName set;
FcExprPage *page;
- if (--config->ref > 0)
+ if (FcRefDec (&config->ref) != 1)
return;
if (config == _fcConfig)
} FcSubState;
static FcValue
-FcConfigPromote (FcValue v, FcValue u)
+FcConfigPromote (FcValue v, FcValue u, FcValuePromotionBuffer *buf)
{
if (v.type == FcTypeInteger)
{
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;
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) {
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)
{
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) {
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;
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));
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)
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)
{
if (src)
{
- if (src->ref != FC_REF_CONSTANT)
- src->ref++;
+ if (!FcRefIsConst (&src->ref))
+ FcRefInc (&src->ref);
else
FcCacheObjectReference (src);
}
if (!a || !b)
return FcFalse;
- if (a->ref == FC_REF_CONSTANT) {
+ if (FcRefIsConst (&a->ref)) {
if (changed)
*changed = FcFalse;
return FcFalse;
freezer->charsets_allocated++;
- ent->set.ref = FC_REF_CONSTANT;
+ FcRefSetConst (&ent->set.ref);
ent->set.num = fcs->num;
if (fcs->num)
{
FcChar16 *numbers;
int i;
- if (cs->ref != FC_REF_CONSTANT)
+ if (!FcRefIsConst (&cs->ref))
{
if (!serialize->cs_freezer)
{
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)
if (!cs_serialized)
return NULL;
- cs_serialized->ref = FC_REF_CONSTANT;
+ FcRefSetConst (&cs_serialized->ref);
cs_serialized->num = cs->num;
if (cs->num)
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"
#include <stdio.h>
#include <string.h>
#include <ctype.h>
+#include <assert.h>
#include <errno.h>
#include <unistd.h>
#include <stddef.h>
#define FcPrivate
#endif
+FC_ASSERT_STATIC (sizeof (FcRef) == sizeof (int));
+
typedef enum _FcValueBinding {
FcValueBindingWeak, FcValueBindingStrong, FcValueBindingSame
} FcValueBinding;
int num;
int size;
intptr_t elts_offset;
- int ref;
+ FcRef ref;
};
#define FcPatternElts(p) FcOffsetMember(p,elts_offset,FcPatternElt)
} 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;
#define FcCharSetNumbers(c) FcOffsetMember(c,numbers_offset,FcChar16)
struct _FcStrSet {
- int ref; /* reference count */
+ FcRef ref; /* reference count */
int num;
int size;
FcChar8 **strs;
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 */
};
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 */
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);
FcSharedStr (const FcChar8 *name);
FcPrivate FcBool
-FcSharedStrFree (const FcChar8 *name);
+FcSharedStrFree (FcChar8 *name);
FcPrivate FcChar32
FcStringHash (const FcChar8 *s);
* 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;
/*
* 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;
-
- memset (ls.map, '\0', sizeof (ls.map));
- ls.map_size = NUM_LANG_SET_MAP;
- ls.extra = 0;
+ int id;
+ typedef struct {
+ FcLangSet ls;
+ FcStrSet strs;
+ FcChar8 *str;
+ } FcLangSetPromotionBuffer;
+ FcLangSetPromotionBuffer *buf = (FcLangSetPromotionBuffer *) vbuf;
+
+ 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
*/
#include "fcint.h"
-#include <assert.h>
-#include <string.h>
-#include <ctype.h>
-#include <stdio.h>
static double
FcCompareNumber (FcValue *value1, FcValue *value2)
#include <config.h>
#endif
+#define FC_STMT_START do
+#define FC_STMT_END while (0)
/* mutex */
#include "fcint.h"
#include "fcftint.h"
-#include <stdlib.h>
-#include <string.h>
-#include <assert.h>
+
+/* Objects MT-safe for readonly access. */
FcPattern *
FcPatternCreate (void)
p->num = 0;
p->size = 0;
p->elts_offset = FcPtrToOffset (p, NULL);
- p->ref = 1;
+ FcRefInit (&p->ref, 1);
return 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);
FcPatternElt *e;
FcValueListPtr l, *prev;
- if (p->ref == FC_REF_CONSTANT)
+ if (FcRefIsConst (&p->ref))
goto bail0;
/*
FcPatternElt *e;
FcValueListPtr new, *prev;
- if (p->ref == FC_REF_CONSTANT)
+ if (FcRefIsConst (&p->ref))
goto bail0;
new = FcValueListCreate ();
void
FcPatternReference (FcPattern *p)
{
- if (p->ref != FC_REF_CONSTANT)
- p->ref++;
+ if (!FcRefIsConst (&p->ref))
+ FcRefInc (&p->ref);
else
FcCacheObjectReference (p);
}
* significant by any means. */
FcBool
-FcSharedStrFree (const FcChar8 *name)
+FcSharedStrFree (FcChar8 *name)
{
free (name);
return FcTrue;
const FcChar8 *
FcSharedStr (const FcChar8 *name)
{
- return strdup (name);
+ return strdup ((const char *) name);
}
FcBool
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)
#include <windows.h>
#endif
+/* Objects MT-safe for readonly access. */
+
FcChar8 *
FcStrCopy (const FcChar8 *s)
{
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;
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 *
if (!list)
return 0;
list->set = set;
- set->ref++;
+ FcRefInc (&set->ref);
list->n = 0;
return list;
}