Detect the overflow for the object ID
Continue to increase the object id even after FcFini() and detect the overflow. that would be rather easier than reset the object id with the complicated mutex and atomic functions. This situation would be quite unlikely to happen though
This commit is contained in:
parent
f053231186
commit
09edd84cf8
22
src/fcobjs.c
22
src/fcobjs.c
|
@ -51,6 +51,8 @@ FcObjectFini (void)
|
||||||
|
|
||||||
retry:
|
retry:
|
||||||
ots = fc_atomic_ptr_get (&other_types);
|
ots = fc_atomic_ptr_get (&other_types);
|
||||||
|
if (!ots)
|
||||||
|
return;
|
||||||
if (!fc_atomic_ptr_cmpexch (&other_types, ots, NULL))
|
if (!fc_atomic_ptr_cmpexch (&other_types, ots, NULL))
|
||||||
goto retry;
|
goto retry;
|
||||||
|
|
||||||
|
@ -68,6 +70,8 @@ static FcObjectType *
|
||||||
_FcObjectLookupOtherTypeByName (const char *str, FcObject *id)
|
_FcObjectLookupOtherTypeByName (const char *str, FcObject *id)
|
||||||
{
|
{
|
||||||
struct FcObjectOtherTypeInfo *ots, *ot;
|
struct FcObjectOtherTypeInfo *ots, *ot;
|
||||||
|
static fc_atomic_int_t first_id = 0;
|
||||||
|
static FcBool overflow = FcFalse;
|
||||||
|
|
||||||
retry:
|
retry:
|
||||||
ots = fc_atomic_ptr_get (&other_types);
|
ots = fc_atomic_ptr_get (&other_types);
|
||||||
|
@ -76,6 +80,11 @@ retry:
|
||||||
if (0 == strcmp (ot->object.object, str))
|
if (0 == strcmp (ot->object.object, str))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
if (!ots)
|
||||||
|
{
|
||||||
|
first_id = fc_atomic_int_add (next_id, 0);
|
||||||
|
overflow = FcFalse;
|
||||||
|
}
|
||||||
if (!ot)
|
if (!ot)
|
||||||
{
|
{
|
||||||
ot = malloc (sizeof (*ot));
|
ot = malloc (sizeof (*ot));
|
||||||
|
@ -84,14 +93,25 @@ retry:
|
||||||
|
|
||||||
ot->object.object = (char *) FcStrdup (str);
|
ot->object.object = (char *) FcStrdup (str);
|
||||||
ot->object.type = FcTypeUnknown;
|
ot->object.type = FcTypeUnknown;
|
||||||
|
retry_id:
|
||||||
ot->id = fc_atomic_int_add (next_id, +1);
|
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;
|
ot->next = ots;
|
||||||
|
|
||||||
if (!fc_atomic_ptr_cmpexch (&other_types, ots, ot)) {
|
if (!fc_atomic_ptr_cmpexch (&other_types, ots, ot)) {
|
||||||
if (ot->object.object)
|
if (ot->object.object)
|
||||||
free (ot->object.object);
|
free (ot->object.object);
|
||||||
free (ot);
|
free (ot);
|
||||||
fc_atomic_int_add (next_id, -1);
|
|
||||||
goto retry;
|
goto retry;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue