Web lists-archives.com

Re: libsecret and dlopen/dlclose thread cleanup, dlopen freeze


You cannot ever unload libgobject - and any other gobject based libraries - with dlclose() after dlopen()-ing them. The type system cannot be reset on library unload, and thus types that were registered once will still be alive the next time you load the library. Additionally, GLib and GObject and GIO have threads and additional state created for things like GDBus, which libsecret uses internally to talk to the secrets service.

In short: if you want to have a plugin that talks to the password and secret storage through the Secret Service DBus API, you will have to use a library that allows unloading and reloading; likely only libdbus. Alternatively, do not allow disabling the plugin if you want to use libsecret.


On Sun, 5 Feb 2017 at 10:27, Gábor Csárdi <csardi.gabor+gtk-list@xxxxxxxxx> wrote:
Hi all,

I have a plugin that uses libsecret, and thus glib, on Linux. (It is a package for R.)

It is loaded with dlopen(), and it (ideally) can be unloaded with dlclose(). I use the synchronous libsecret functions, which AFAICT run a temporary glib event loop for each libsecret query. E.g. this is what I am doing:

  GError *err = NULL;
  gchar *password = secret_password_lookup_sync (
    /* cancellable = */ NULL,
    "service", cservice,
    "username", cusername,

  if (err) {
    if (password) secret_password_free(password);
    keyring_secret_service_handle_status("get", TRUE, err);

  if (!password) {
    error("keyring item not found");
    return R_NilValue;

  } else {
    /* ... */
    return result;

When the lib is unloaded I call secret_service_disconnect(), I checked that this is called. I do link to libgobject-2.0, I even call g_type_ensure (G_TYPE_OBJECT) to make sure that the constructors in libgobject run.

However, it seems that the worker threads for glib (?) are never cleaned up. Even if I dlclose() the lib, they are there. What am I missing here? Do I have to eliminate the threads manually? If yes, how can I do that?

An even bigger problem is, that if I dlopen() the same plugin again, and call a libsecret function, then it just freezes with this:

(process:18663): GLib-GObject-WARNING **: cannot register existing type 'SecretService'
(process:18663): GLib-GObject-CRITICAL **: g_type_add_interface_static: assertion 'G_TYPE_IS_INSTANTIATABLE (instance_type)' failed
(process:18663): GLib-GObject-CRITICAL **: g_type_add_interface_static: assertion 'G_TYPE_IS_INSTANTIATABLE (instance_type)' failed
(process:18663): GLib-CRITICAL **: g_once_init_leave: assertion 'result != 0' failed
(process:18663): GLib-GIO-CRITICAL **: g_async_initable_new_valist_async: assertion 'G_TYPE_IS_ASYNC_INITABLE (object_type)' failed

Which seems to suggest that I need to unregister the SecretService type at dlclose(). Is that right? How can I do that?

I don't have too much experience with glib, and I am just probably doing something wrong, or missing something. Any help is appreciated. I can also put together a reproducible example if needed.

Thanks, Best,
gtk-list mailing list
[@] ebassi [@gmail.com]
gtk-list mailing list