gnutls: revert part of the gcrypt-removing patch
authorDan Winship <danw@gnome.org>
Sun, 4 Dec 2011 11:59:51 +0000 (12:59 +0100)
committerDan Winship <danw@gnome.org>
Sun, 4 Dec 2011 11:59:51 +0000 (12:59 +0100)
I thought we could get rid of the "keep the module from being
unloaded" hack now, but it appears that we can't.

tls/gnutls/gtlsbackend-gnutls.c

index 3597753..493a044 100644 (file)
@@ -37,14 +37,11 @@ struct _GTlsBackendGnutlsPrivate
   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
@@ -54,25 +51,35 @@ gtls_log_func (int level, const char *msg)
 }
 #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);
 }