[glib] Add g_type_ensure() and use it rather than playing games with volatile



commit e011d2c92162d25a6e6d5f67d462edfeb4af3d7a
Author: Dan Winship <danw gnome org>
Date:   Sun Jan 3 14:47:56 2010 -0500

    Add g_type_ensure() and use it rather than playing games with volatile
    
    https://bugzilla.gnome.org/show_bug.cgi?id=605976

 docs/reference/gobject/gobject-sections.txt |    1 +
 gio/gicon.c                                 |   10 ++----
 gio/ginetaddress.c                          |    4 +--
 gio/giomodule.c                             |   38 ++++++++++++------------
 gio/gresolver.c                             |    5 +--
 gio/gsocket.c                               |    4 +--
 gio/gsocketconnection.c                     |    6 +--
 gio/gsocketcontrolmessage.c                 |    8 +----
 gio/gunixconnection.c                       |    5 +--
 gobject/gobject.symbols                     |    1 +
 gobject/gtype.c                             |   43 +++++++++++++++++++++++----
 gobject/gtype.h                             |    2 +
 12 files changed, 72 insertions(+), 55 deletions(-)
---
diff --git a/docs/reference/gobject/gobject-sections.txt b/docs/reference/gobject/gobject-sections.txt
index 0540e84..5d3dc1a 100644
--- a/docs/reference/gobject/gobject-sections.txt
+++ b/docs/reference/gobject/gobject-sections.txt
@@ -98,6 +98,7 @@ g_type_add_interface_check
 g_type_remove_interface_check
 GTypeInterfaceCheckFunc
 g_type_value_table_peek
+g_type_ensure
 
 G_DEFINE_TYPE
 G_DEFINE_TYPE_WITH_CODE
diff --git a/gio/gicon.c b/gio/gicon.c
index abc9a8d..df44bb0 100644
--- a/gio/gicon.c
+++ b/gio/gicon.c
@@ -375,12 +375,10 @@ g_icon_new_from_tokens (char   **tokens,
 static void
 ensure_builtin_icon_types (void)
 {
-  static volatile GType t;
-  t = g_themed_icon_get_type ();
-  t = g_file_icon_get_type ();
-  t = g_emblemed_icon_get_type ();
-  t = g_emblem_get_type ();
-  (t); /* To avoid -Wunused-but-set-variable */
+  g_type_ensure (G_TYPE_THEMED_ICON);
+  g_type_ensure (G_TYPE_FILE_ICON);
+  g_type_ensure (G_TYPE_EMBLEMED_ICON);
+  g_type_ensure (G_TYPE_EMBLEM);
 }
 
 /**
diff --git a/gio/ginetaddress.c b/gio/ginetaddress.c
index 7de45e7..0b1a1ad 100644
--- a/gio/ginetaddress.c
+++ b/gio/ginetaddress.c
@@ -401,7 +401,6 @@ g_inet_address_init (GInetAddress *address)
 GInetAddress *
 g_inet_address_new_from_string (const gchar *string)
 {
-  volatile GType type;
 #ifdef G_OS_WIN32
   struct sockaddr_storage sa;
   struct sockaddr_in *sin = (struct sockaddr_in *)&sa;
@@ -413,8 +412,7 @@ g_inet_address_new_from_string (const gchar *string)
 #endif
 
   /* Make sure _g_networking_init() has been called */
-  type = g_inet_address_get_type ();
-  (type); /* To avoid -Wunused-but-set-variable */
+  g_type_ensure (G_TYPE_INET_ADDRESS);
 
 #ifdef G_OS_WIN32
   memset (&sa, 0, sizeof (sa));
diff --git a/gio/giomodule.c b/gio/giomodule.c
index d8ce138..37a9e70 100644
--- a/gio/giomodule.c
+++ b/gio/giomodule.c
@@ -909,39 +909,39 @@ _g_io_modules_ensure_loaded (void)
       g_io_module_scope_free (scope);
 
       /* Initialize types from built-in "modules" */
-      g_null_settings_backend_get_type ();
-      g_memory_settings_backend_get_type ();
+      g_type_ensure (g_null_settings_backend_get_type ());
+      g_type_ensure (g_memory_settings_backend_get_type ());
 #if defined(HAVE_SYS_INOTIFY_H) || defined(HAVE_LINUX_INOTIFY_H)
-      _g_inotify_directory_monitor_get_type ();
-      _g_inotify_file_monitor_get_type ();
+      g_type_ensure (_g_inotify_directory_monitor_get_type ());
+      g_type_ensure (_g_inotify_file_monitor_get_type ());
 #endif
 #if defined(HAVE_FEN)
-      _g_fen_directory_monitor_get_type ();
-      _g_fen_file_monitor_get_type ();
+      g_type_ensure (_g_fen_directory_monitor_get_type ());
+      g_type_ensure (_g_fen_file_monitor_get_type ());
 #endif
 #ifdef G_OS_WIN32
-      _g_win32_volume_monitor_get_type ();
-      g_win32_directory_monitor_get_type ();
-      g_registry_backend_get_type ();
+      g_type_ensure (_g_win32_volume_monitor_get_type ());
+      g_type_ensure (g_win32_directory_monitor_get_type ());
+      g_type_ensure (g_registry_backend_get_type ());
 #endif
 #ifdef HAVE_CARBON
       g_nextstep_settings_backend_get_type ();
 #endif
 #ifdef G_OS_UNIX
-      _g_unix_volume_monitor_get_type ();
+      g_type_ensure (_g_unix_volume_monitor_get_type ());
 #endif
 #ifdef G_OS_WIN32
-      _g_winhttp_vfs_get_type ();
+      g_type_ensure (_g_winhttp_vfs_get_type ());
 #endif
-      _g_local_vfs_get_type ();
-      _g_dummy_proxy_resolver_get_type ();
-      _g_socks4a_proxy_get_type ();
-      _g_socks4_proxy_get_type ();
-      _g_socks5_proxy_get_type ();
-      _g_dummy_tls_backend_get_type ();
-      g_network_monitor_base_get_type ();
+      g_type_ensure (_g_local_vfs_get_type ());
+      g_type_ensure (_g_dummy_proxy_resolver_get_type ());
+      g_type_ensure (_g_socks4a_proxy_get_type ());
+      g_type_ensure (_g_socks4_proxy_get_type ());
+      g_type_ensure (_g_socks5_proxy_get_type ());
+      g_type_ensure (_g_dummy_tls_backend_get_type ());
+      g_type_ensure (g_network_monitor_base_get_type ());
 #ifdef HAVE_NETLINK
-      _g_network_monitor_netlink_get_type ();
+      g_type_ensure (_g_network_monitor_netlink_get_type ());
 #endif
     }
 
diff --git a/gio/gresolver.c b/gio/gresolver.c
index 9f80fc0..811c971 100644
--- a/gio/gresolver.c
+++ b/gio/gresolver.c
@@ -146,8 +146,6 @@ g_resolver_real_lookup_service_finish (GResolver            *resolver,
 static void
 g_resolver_class_init (GResolverClass *resolver_class)
 {
-  volatile GType type;
-
   /* Automatically pass these over to the lookup_records methods */
   resolver_class->lookup_service = g_resolver_real_lookup_service;
   resolver_class->lookup_service_async = g_resolver_real_lookup_service_async;
@@ -156,8 +154,7 @@ g_resolver_class_init (GResolverClass *resolver_class)
   g_type_class_add_private (resolver_class, sizeof (GResolverPrivate));
 
   /* Make sure _g_networking_init() has been called */
-  type = g_inet_address_get_type ();
-  (type); /* To avoid -Wunused-but-set-variable */
+  g_type_ensure (G_TYPE_INET_ADDRESS);
 
   /* Initialize _g_resolver_addrinfo_hints */
 #ifdef AI_ADDRCONFIG
diff --git a/gio/gsocket.c b/gio/gsocket.c
index 0b8d91b..9062cc9 100644
--- a/gio/gsocket.c
+++ b/gio/gsocket.c
@@ -742,11 +742,9 @@ static void
 g_socket_class_init (GSocketClass *klass)
 {
   GObjectClass *gobject_class G_GNUC_UNUSED = G_OBJECT_CLASS (klass);
-  volatile GType type;
 
   /* Make sure winsock has been initialized */
-  type = g_inet_address_get_type ();
-  (type); /* To avoid -Wunused-but-set-variable */
+  g_type_ensure (G_TYPE_INET_ADDRESS);
 
 #ifdef SIGPIPE
   /* There is no portable, thread-safe way to avoid having the process
diff --git a/gio/gsocketconnection.c b/gio/gsocketconnection.c
index ee391ab..a881a47 100644
--- a/gio/gsocketconnection.c
+++ b/gio/gsocketconnection.c
@@ -602,12 +602,10 @@ g_socket_connection_factory_register_type (GType         g_type,
 static void
 init_builtin_types (void)
 {
-  volatile GType a_type;
 #ifndef G_OS_WIN32
-  a_type = g_unix_connection_get_type ();
+  g_type_ensure (G_TYPE_UNIX_CONNECTION);
 #endif
-  a_type = g_tcp_connection_get_type ();
-  (a_type); /* To avoid -Wunused-but-set-variable */
+  g_type_ensure (G_TYPE_TCP_CONNECTION);
 }
 
 /**
diff --git a/gio/gsocketcontrolmessage.c b/gio/gsocketcontrolmessage.c
index 6b1ad8d..4cd3ed8 100644
--- a/gio/gsocketcontrolmessage.c
+++ b/gio/gsocketcontrolmessage.c
@@ -177,15 +177,11 @@ g_socket_control_message_deserialize (int      level,
   GType *message_types;
   guint n_message_types;
   int i;
-#ifndef G_OS_WIN32
-  volatile GType a_type;
-#endif
 
   /* Ensure we know about the built in types */
 #ifndef G_OS_WIN32
-  a_type = g_unix_credentials_message_get_type ();
-  a_type = g_unix_fd_message_get_type ();
-  (a_type); /* To avoid -Wunused-but-set-variable */
+  g_type_ensure (G_TYPE_UNIX_CREDENTIALS_MESSAGE);
+  g_type_ensure (G_TYPE_UNIX_FD_MESSAGE);
 #endif
 
   message_types = g_type_children (G_TYPE_SOCKET_CONTROL_MESSAGE, &n_message_types);
diff --git a/gio/gunixconnection.c b/gio/gunixconnection.c
index 70a31a4..b0ac143 100644
--- a/gio/gunixconnection.c
+++ b/gio/gunixconnection.c
@@ -473,7 +473,6 @@ g_unix_connection_receive_credentials (GUnixConnection      *connection,
   gint nscm;
   GSocket *socket;
   gint n;
-  volatile GType credentials_message_gtype;
   gssize num_bytes_read;
 #ifdef __linux__
   gboolean turn_off_so_passcreds;
@@ -543,9 +542,7 @@ g_unix_connection_receive_credentials (GUnixConnection      *connection,
   }
 #endif
 
-  /* ensure the type of GUnixCredentialsMessage has been registered with the type system */
-  credentials_message_gtype = G_TYPE_UNIX_CREDENTIALS_MESSAGE;
-  (credentials_message_gtype); /* To avoid -Wunused-but-set-variable */
+  g_type_ensure (G_TYPE_UNIX_CREDENTIALS_MESSAGE);
   num_bytes_read = g_socket_receive_message (socket,
                                              NULL, /* GSocketAddress **address */
                                              NULL,
diff --git a/gobject/gobject.symbols b/gobject/gobject.symbols
index 220b487..136045b 100644
--- a/gobject/gobject.symbols
+++ b/gobject/gobject.symbols
@@ -336,6 +336,7 @@ g_type_default_interface_peek
 g_type_default_interface_ref
 g_type_default_interface_unref
 g_type_depth
+g_type_ensure
 g_type_free_instance
 g_type_from_name
 g_type_fundamental
diff --git a/gobject/gtype.c b/gobject/gtype.c
index 43fdbc6..f9e5a61 100644
--- a/gobject/gtype.c
+++ b/gobject/gtype.c
@@ -4275,7 +4275,7 @@ g_type_init_with_debug_flags (GTypeDebugFlags debug_flags)
   const gchar *env_string;
   GTypeInfo info;
   TypeNode *node;
-  volatile GType votype;
+  GType type;
 
   G_LOCK (type_init_lock);
   
@@ -4316,16 +4316,16 @@ g_type_init_with_debug_flags (GTypeDebugFlags debug_flags)
   /* void type G_TYPE_NONE
    */
   node = type_node_fundamental_new_W (G_TYPE_NONE, g_intern_static_string ("void"), 0);
-  votype = NODE_TYPE (node);
-  g_assert (votype == G_TYPE_NONE);
+  type = NODE_TYPE (node);
+  g_assert (type == G_TYPE_NONE);
   
   /* interface fundamental type G_TYPE_INTERFACE (!classed)
    */
   memset (&info, 0, sizeof (info));
   node = type_node_fundamental_new_W (G_TYPE_INTERFACE, g_intern_static_string ("GInterface"), G_TYPE_FLAG_DERIVABLE);
-  votype = NODE_TYPE (node);
+  type = NODE_TYPE (node);
   type_data_make_W (node, &info, NULL);
-  g_assert (votype == G_TYPE_INTERFACE);
+  g_assert (type == G_TYPE_INTERFACE);
   
   G_WRITE_UNLOCK (&type_rw_lock);
   
@@ -4333,7 +4333,7 @@ g_type_init_with_debug_flags (GTypeDebugFlags debug_flags)
 
   /* G_TYPE_TYPE_PLUGIN
    */
-  votype = g_type_plugin_get_type ();
+  g_type_ensure (g_type_plugin_get_type ());
   
   /* G_TYPE_* value types
    */
@@ -4653,3 +4653,34 @@ g_type_class_get_private (GTypeClass *klass,
 
   return G_STRUCT_MEMBER_P (klass, offset);
 }
+
+/**
+ * g_type_ensure:
+ * @type: a #GType.
+ *
+ * Ensures that the indicated @type has been registered with the
+ * type system, and its _class_init() method has been run.
+ *
+ * In theory, simply calling the type's _get_type() method (or using
+ * the corresponding macro) is supposed take care of this. However,
+ * _get_type() methods are often marked %G_GNUC_CONST for performance
+ * reasons, even though this is technically incorrect (since
+ * %G_GNUC_CONST requires that the function not have side effects,
+ * which _get_type() methods do on the first call). As a result, if
+ * you write a bare call to a _get_type() macro, it may get optimized
+ * out by the compiler. Using g_type_ensure() guarantees that the
+ * type's _get_type() method is called.
+ *
+ * Since: 2.34
+ */
+void
+g_type_ensure (GType type)
+{
+  /* In theory, @type has already been resolved and so there's nothing
+   * to do here. But this protects us in the case where the function
+   * gets inlined (as it might in g_type_init_with_debug_flags()
+   * above).
+   */
+  if (G_UNLIKELY (type == (GType)-1))
+    g_error ("can't happen");
+}
diff --git a/gobject/gtype.h b/gobject/gtype.h
index abd033a..768ad00 100644
--- a/gobject/gtype.h
+++ b/gobject/gtype.h
@@ -1258,6 +1258,8 @@ void      g_type_add_class_private      (GType    		     class_type,
 gpointer  g_type_class_get_private      (GTypeClass 		    *klass,
 					 GType			     private_type);
 
+GLIB_AVAILABLE_IN_2_34
+void      g_type_ensure                 (GType                       type);
 
 /* --- GType boilerplate --- */
 /**



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]