loaders: Change method used to not unload loaders

It appears that in certain environments (homebrew on MacOS) the linker
does not like the -z nodelete option, so handle this differently.

old/legacy-imlib2#8
This commit is contained in:
Kim Woelders 2023-04-03 06:50:21 +02:00
parent 7c18c9aca1
commit 9468f7132c
6 changed files with 44 additions and 9 deletions

View File

@ -197,24 +197,33 @@ int __imlib_LoadProgressRows(ImlibImage * im,
#define IMLIB2_LOADER_VERSION 2
#define LDR_FLAG_KEEP 0x01 /* Don't unload loader */
typedef struct {
unsigned char ldr_version; /* Module ABI version */
unsigned char rsvd;
unsigned char ldr_flags; /* LDR_FLAG_... */
unsigned short num_formats; /* Length og known extension list */
const char *const *formats; /* Known extension list */
int (*load)(ImlibImage * im, int load_data);
int (*save)(ImlibImage * im);
} ImlibLoaderModule;
#define IMLIB_LOADER(_fmts, _ldr, _svr) \
#define IMLIB_LOADER_(_fmts, _ldr, _svr, _flags) \
__EXPORT__ ImlibLoaderModule loader = { \
.ldr_version = IMLIB2_LOADER_VERSION, \
.ldr_flags = _flags, \
.num_formats = ARRAY_SIZE(_fmts), \
.formats = _fmts, \
.load = _ldr, \
.save = _svr, \
}
#define IMLIB_LOADER(_fmts, _ldr, _svr) \
IMLIB_LOADER_(_fmts, _ldr, _svr, 0)
#define IMLIB_LOADER_KEEP(_fmts, _ldr, _svr) \
IMLIB_LOADER_(_fmts, _ldr, _svr, LDR_FLAG_KEEP)
#define QUIT_WITH_RC(_err) { rc = _err; goto quit; }
#define PCAST(T, p) ((T)(const void *)(p))

View File

@ -15,6 +15,7 @@
#define DP(fmt...) DC(DBG_LOAD, fmt)
static ImlibLoader *loaders = NULL;
static ImlibLoader *loaders_unloaded = NULL;
static char loaders_loaded = 0;
typedef struct {
@ -161,11 +162,24 @@ __imlib_LookupLoaderByModulePath(const char *file)
static ImlibLoader *
__imlib_ProduceLoader(const char *file)
{
ImlibLoader *l;
ImlibLoader *l, *l_prev;
ImlibLoaderModule *m;
DP("%s: %s\n", __func__, file);
/* Check unloaded loaders */
for (l = loaders_unloaded, l_prev = NULL; l; l_prev = l, l = l->next)
{
if (strcmp(file, l->file) != 0)
continue;
if (l == loaders_unloaded)
loaders_unloaded = l->next;
else
l_prev->next = l->next;
goto found;
}
l = malloc(sizeof(ImlibLoader));
l->handle = dlopen(file, RTLD_NOW | RTLD_LOCAL);
@ -187,6 +201,7 @@ __imlib_ProduceLoader(const char *file)
l->file = strdup(file);
l->name = m->formats[0];
found:
l->next = loaders;
loaders = l;
@ -201,9 +216,18 @@ __imlib_ProduceLoader(const char *file)
static void
__imlib_ConsumeLoader(ImlibLoader * l)
{
free(l->file);
if (l->module->ldr_flags & LDR_FLAG_KEEP)
{
/* Not un/re-loadable - Move to unloaded loaders list */
l->next = loaders_unloaded;
loaders_unloaded = l;
return;
}
if (l->handle)
dlclose(l->handle);
free(l->file);
free(l);
}

View File

@ -5,9 +5,11 @@
#define IMLIB2_LOADER_VERSION 2
#define LDR_FLAG_KEEP 0x01 /* Don't unload loader */
typedef struct {
unsigned char ldr_version; /* Module ABI version */
unsigned char rsvd;
unsigned char ldr_flags; /* LDR_FLAG_... */
unsigned short num_formats; /* Length og known extension list */
const char *const *formats; /* Known extension list */
int (*load)(ImlibImage * im, int load_data);

View File

@ -91,7 +91,7 @@ gif_la_LIBTOOLFLAGS = --tag=disable-static
heif_la_SOURCES = loader_heif.c
heif_la_CPPFLAGS = $(HEIF_CFLAGS) $(AM_CPPFLAGS)
heif_la_LDFLAGS = -module -avoid-version -Wl,-z,nodelete
heif_la_LDFLAGS = -module -avoid-version
heif_la_LIBADD = $(HEIF_LIBS) $(top_builddir)/src/lib/libImlib2.la
heif_la_LIBTOOLFLAGS = --tag=disable-static
@ -142,7 +142,7 @@ ps_la_LIBTOOLFLAGS = --tag=disable-static
svg_la_SOURCES = loader_svg.c
svg_la_CPPFLAGS = $(SVG_CFLAGS) $(AM_CPPFLAGS)
svg_la_LDFLAGS = -module -avoid-version -Wl,-z,nodelete
svg_la_LDFLAGS = -module -avoid-version
svg_la_LIBADD = $(SVG_LIBS) $(top_builddir)/src/lib/libImlib2.la
svg_la_LIBTOOLFLAGS = --tag=disable-static

View File

@ -172,4 +172,4 @@ _load(ImlibImage * im, int load_data)
return rc;
}
IMLIB_LOADER(_formats, _load, NULL);
IMLIB_LOADER_KEEP(_formats, _load, NULL);

View File

@ -238,4 +238,4 @@ _load(ImlibImage * im, int load_data)
return rc;
}
IMLIB_LOADER(_formats, _load, NULL);
IMLIB_LOADER_KEEP(_formats, _load, NULL);