From dbbb46207e243d07d2e4c4d35547fc7521c9c62f Mon Sep 17 00:00:00 2001 From: Akira TAGOH Date: Fri, 16 May 2025 19:45:41 +0900 Subject: [PATCH] Drop FcObjectFini() from FcFini() to fix memory leaks Initialization around FcObject has been integrated into FcConfig instance. they are freed once all FcConfig instances has been destroyed. So we don't need to call FcObjectFini() from FcFini() anymore. Changelog: fixed --- src/fccfg.c | 2 ++ src/fcinit.c | 1 - src/fcint.h | 2 ++ src/fcobjs.c | 23 ++++++++++++++++++++++- test/test-bz106632.c | 1 + 5 files changed, 27 insertions(+), 2 deletions(-) diff --git a/src/fccfg.c b/src/fccfg.c index 0756698e..0d521018 100644 --- a/src/fccfg.c +++ b/src/fccfg.c @@ -210,6 +210,7 @@ FcConfigCreate (void) config->prefer_app_fonts = FcFalse; FcRefInit (&config->ref, 1); + FcObjectInit(); return config; @@ -356,6 +357,7 @@ FcConfigDestroy (FcConfig *config) if (FcRefDec (&config->ref) != 1) return; + FcObjectFini(); (void)fc_atomic_ptr_cmpexch (&_fcConfig, config, NULL); FcStrSetDestroy (config->configDirs); diff --git a/src/fcinit.c b/src/fcinit.c index 33e1d6e8..9c66515c 100644 --- a/src/fcinit.c +++ b/src/fcinit.c @@ -214,7 +214,6 @@ void FcFini (void) { FcConfigFini(); - FcObjectFini(); FcCacheFini(); } diff --git a/src/fcint.h b/src/fcint.h index 2dd0bf57..67a16046 100644 --- a/src/fcint.h +++ b/src/fcint.h @@ -1413,6 +1413,8 @@ FcPrivate FcChar8 * FcStrSerialize (FcSerialize *serialize, const FcChar8 *str); /* fcobjs.c */ +FcPrivate void +FcObjectInit (void); FcPrivate void FcObjectFini (void); diff --git a/src/fcobjs.c b/src/fcobjs.c index e21d7a3d..c7bcb0cf 100644 --- a/src/fcobjs.c +++ b/src/fcobjs.c @@ -43,6 +43,13 @@ struct FcObjectOtherTypeInfo { FcObjectType object; FcObject id; } *other_types; +static FcRef obj_ref = { .count = 0 }; + +void +FcObjectInit (void) +{ + FcRefInc (&obj_ref); +} void FcObjectFini (void) @@ -50,11 +57,17 @@ FcObjectFini (void) struct FcObjectOtherTypeInfo *ots, *ot; retry: + if (obj_ref.count < 1) + fprintf (stderr, "Fontconfig warning: too many caller of FcObjectFini()\n"); + if (obj_ref.count >= 1 && FcRefDec (&obj_ref) != 1) + return; 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)) { + FcRefInc (&obj_ref); goto retry; + } while (ots) { ot = ots->next; @@ -69,9 +82,17 @@ static FcObjectType * _FcObjectLookupOtherTypeByName (const char *str, FcObject *id) { struct FcObjectOtherTypeInfo *ots, *ot; + static FcBool warn = FcFalse; retry: ots = fc_atomic_ptr_get (&other_types); + if (obj_ref.count < 1) { + if (!warn) { + fprintf (stderr, "Fontconfig warning: using without calling FcInit()\n"); + warn = FcTrue; + } + FcObjectInit(); + } for (ot = ots; ot; ot = ot->next) if (0 == strcmp (ot->object.object, str)) diff --git a/test/test-bz106632.c b/test/test-bz106632.c index 3c56cb72..1e18d5c0 100644 --- a/test/test-bz106632.c +++ b/test/test-bz106632.c @@ -305,6 +305,7 @@ bail: FcStrFree (fontdir); if (cachedir) FcStrFree (cachedir); + FcFini(); return ret; } -- GitLab