GTlsDatabase *default_database;
};
-static void gtls_gnutls_init (void);
static void g_tls_backend_gnutls_interface_init (GTlsBackendInterface *iface);
G_DEFINE_DYNAMIC_TYPE_EXTENDED (GTlsBackendGnutls, g_tls_backend_gnutls, G_TYPE_OBJECT, 0,
G_IMPLEMENT_INTERFACE_DYNAMIC (G_TYPE_TLS_BACKEND,
- g_tls_backend_gnutls_interface_init);
- gtls_gnutls_init ();
- )
+ g_tls_backend_gnutls_interface_init);)
#ifdef GTLS_GNUTLS_DEBUG
static void
}
#endif
-static void
-gtls_gnutls_init (void)
+static gpointer
+gtls_gnutls_init (gpointer data)
{
gnutls_global_init ();
#ifdef GTLS_GNUTLS_DEBUG
gnutls_global_set_log_function (gtls_log_func);
gnutls_global_set_log_level (9);
+#endif
- /* Leak the module to keep it from being unloaded and breaking
- * the pointer to gtls_log_func().
- */
+ /* Leak the module to keep it from being unloaded. */
g_type_plugin_use (g_type_get_plugin (G_TYPE_TLS_BACKEND_GNUTLS));
-#endif
+ return NULL;
}
+static GOnce gnutls_inited = G_ONCE_INIT;
+
static void
g_tls_backend_gnutls_init (GTlsBackendGnutls *backend)
{
+ /* Once we call gtls_gnutls_init(), we can't allow the module to be
+ * unloaded (since if gnutls gets unloaded but gcrypt doesn't, then
+ * gcrypt will have dangling pointers to gnutls's mutex functions).
+ * So we initialize it from here rather than at class init time so
+ * that it doesn't happen unless the app is actually using TLS (as
+ * opposed to just calling g_io_modules_scan_all_in_directory()).
+ */
+ g_once (&gnutls_inited, gtls_gnutls_init, NULL);
+
backend->priv = G_TYPE_INSTANCE_GET_PRIVATE (backend, G_TYPE_TLS_BACKEND_GNUTLS, GTlsBackendGnutlsPrivate);
g_mutex_init (&backend->priv->mutex);
}