Will dlclose() reset internal state of libgirepository?

As you may remember we have an open gintro issue since 6 months for a few people using Arch Linux,
which is related to libs like libsoup which are available in different versions, and the fact that libgirepository stores internal state and does not provide a reset() function. See

The correct solution is to start a new process for each processed lib, as starting a new process should reset libgirepository.

But that would require a large rewrite of the existing binding generator script. With all the necessary testing and debugging that may result in 100 hours of work again, and all that for the two or three active users.

So I yesterday had the idea that a call of dlclose() followed by dlopen() may reset the internal state of libgirepository too? Nim is actually using dlopen() for accessing dynamic libs, so I guess there is a way to use dlclose(). Of course, dlclose() is Linux only, Windows has something like LoadLibrary(). But a Linux solution would be fine, I think we have no Windows users with issues.

Unfortunately I can not replicate the hole ARCH LINUX issue, with Gentoo libs as well as with latest libs from gitlab all works for me fine.

Another related, really ugly trick may be to create a renamed copy of libgirepository for each module that we process and to open the renamed clone fresh with dlopen. But maybe libgirepository will notice when its file is renamed and refuse to work.

And one more solution may be to fork libgirepository and to hack it, so that it can reset it state or that it does not load other libs on its own at all. The way we use libgirepository is basically just a parser for the XML GIR files, we just need all the info which are contained in the GIR files for our Nim bindings. Of course now, seven years later, I know that it would have been an option to do not use libgirepository at all but just parse the XML GIR files. But I really can not rewrite all of this myself, it is just too much work.

No, I think the use of dlclose() is a stupid idea. And actually processing the bindings modules for each lib separately as its own process is also stupid. The separate process would remove the troubles when generating the bindings, but the user may have the trouble again later when using the modules. And actually, splittint the whole bindings generation in separate processes for each lib would require a really large rewrite of the bindings generator, for which 100 hours of work may be not sufficient.

From my current understanding we basically have a set of libs compatible with GTK4, and a set compatible with GTK3. Most libs like glib come only in one version and are compatible with both. So my current module creation strategy with a GTK3 set and a GTK4 set is not that wrong.

I think the trouble results from Arch Linux shipping libsoup3, but at the same time shipping libs from the GTK4 set requiring libsoup2.4.

Gentoo ships GTK4, but still mask libsoup3, see net-libs/libsoup – Gentoo Packages

New major parallel-installable release which needs special care to not end up loaded into the same process together with the earlier libsoup ABI. Migration to it is expected for GNOME 42, NOT to be unmasked with GNOME 41.

So what my generator script should do is to look what version of libsoup packages like webkit actually want to use, and then to generate bindings for that libsoup version.

Seems to be simple basically. Unfortunately I have still no Arch Linux available to test. Currently I have the impression that webkit is the only lib from the modules that we generate for the gintro bindings that actually OFFICIALLY uses libsoup. At least that advertises that it uses libsoup. Problems may arise, when libs use libsoup internally but do not advertise it – but I would call that a gobject-introspection bug then.

It is, yes. Unless you can guarantee that nothing uses code from that library anymore, including e.g. threads spawned by that library, and also that all relevant state is reset. It needs very careful design of the library and the application that wants to unload it.

It’s not possible to dlclose() any library registering GTypes, unless they use the dynamic type machinery and you go via the GModule API instead of dlclose(), but that comes with its own set of constraints.

More specifically, it’s not possible to dlclose() GLib, or GTK3/GTK4 and dlopen() the other one some time later.

For libsoup2 vs libsoup3 (and in the future GTK3 vs GTK4) the corresponding GStreamer plugins are loading the libraries at runtime via dlopen() by checking which version is already loaded into the process (in which case that one is used), and otherwise loading whatever version is found. This keeps the choice of the version to the application while allowing two different applications to use two different versions.

It still does not allow for unloading though, which is a whole other can of worms. And of course also does not allow loading both versions into the same process.

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.