summaryrefslogtreecommitdiff
path: root/src/fcobjs.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/fcobjs.c')
-rw-r--r--src/fcobjs.c22
1 files changed, 21 insertions, 1 deletions
diff --git a/src/fcobjs.c b/src/fcobjs.c
index 2895dc0..5e6b091 100644
--- a/src/fcobjs.c
+++ b/src/fcobjs.c
@@ -51,6 +51,8 @@ FcObjectFini (void)
retry:
ots = fc_atomic_ptr_get (&other_types);
+ if (!ots)
+ return;
if (!fc_atomic_ptr_cmpexch (&other_types, ots, NULL))
goto retry;
@@ -68,6 +70,8 @@ static FcObjectType *
_FcObjectLookupOtherTypeByName (const char *str, FcObject *id)
{
struct FcObjectOtherTypeInfo *ots, *ot;
+ static fc_atomic_int_t first_id = 0;
+ static FcBool overflow = FcFalse;
retry:
ots = fc_atomic_ptr_get (&other_types);
@@ -76,6 +80,11 @@ retry:
if (0 == strcmp (ot->object.object, str))
break;
+ if (!ots)
+ {
+ first_id = fc_atomic_int_add (next_id, 0);
+ overflow = FcFalse;
+ }
if (!ot)
{
ot = malloc (sizeof (*ot));
@@ -84,14 +93,25 @@ retry:
ot->object.object = (char *) FcStrdup (str);
ot->object.type = FcTypeUnknown;
+ retry_id:
ot->id = fc_atomic_int_add (next_id, +1);
+ if (overflow && ot->id == first_id)
+ {
+ fprintf (stderr, "Fontconfig error: No object ID to assign\n");
+ abort ();
+ }
+ if (ot->id < (FC_MAX_BASE_OBJECT + FC_EXT_OBJ_INDEX))
+ {
+ overflow = FcTrue;
+ fc_atomic_ptr_cmpexch (&next_id, ot->id + 1, FC_MAX_BASE_OBJECT + FC_EXT_OBJ_INDEX + 1);
+ goto retry_id;
+ }
ot->next = ots;
if (!fc_atomic_ptr_cmpexch (&other_types, ots, ot)) {
if (ot->object.object)
free (ot->object.object);
free (ot);
- fc_atomic_int_add (next_id, -1);
goto retry;
}
}