diff options
Diffstat (limited to 'src/fcobjs.c')
-rw-r--r-- | src/fcobjs.c | 22 |
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; } } |