summaryrefslogtreecommitdiff
path: root/gobject/gtype.h
diff options
context:
space:
mode:
authorAlexander Larsson <alexl@redhat.com>2016-01-29 18:27:14 +0100
committerAlexander Larsson <alexl@redhat.com>2016-02-15 08:36:40 +0100
commit0d89ba778d6d97b7a5de3ba64faf6bf0d0271911 (patch)
tree364cea9f9e8ad7ec261d48ac7e17c9a7972709d9 /gobject/gtype.h
parent3f29f7272c1776997c013b78600700ffab3d7738 (diff)
downloadglib-wip/alexl/versioned-types.tar.gz
Support versions of GTypeswip/alexl/versioned-types
This adds support for registrating multiple versions of the same typename by adding "@@" and a version name when you register the type. This allows you to include a static library in your module that uses gtypes. Normally such types would conflicts if another library also statically linked to the library with the same gtype names, but a different version. However, since the version names are different we avoid this conflict. You can also use this in public types if you want to allow using two libraries with similarly named types to be used in the same process. However, in addition to the gtype versions you then need to solve the symbol name conflicts. This can be done for instance by using dlopen with RTLD_LOCAL, or by introducing ELF symbol versioning. You can query the versions of a type with g_type_[q]version (), and you can look up a name by name and version with g_type_from_name_and_version(). g_type_from_name() returns the unversioned name if one exists (thus putting the burden of using from_name_and_version on the person introducing versioned symbols), and in the case of conflicting versions the alphabetically largest version is used to guarantee stable results.
Diffstat (limited to 'gobject/gtype.h')
-rw-r--r--gobject/gtype.h23
1 files changed, 18 insertions, 5 deletions
diff --git a/gobject/gtype.h b/gobject/gtype.h
index b564bbb96..8678014c4 100644
--- a/gobject/gtype.h
+++ b/gobject/gtype.h
@@ -685,8 +685,15 @@ GLIB_AVAILABLE_IN_ALL
const gchar * g_type_name (GType type);
GLIB_AVAILABLE_IN_ALL
GQuark g_type_qname (GType type);
+GLIB_AVAILABLE_IN_2_48
+const gchar * g_type_version (GType type);
+GLIB_AVAILABLE_IN_2_48
+GQuark g_type_qversion (GType type);
GLIB_AVAILABLE_IN_ALL
GType g_type_from_name (const gchar *name);
+GLIB_AVAILABLE_IN_2_48
+GType g_type_from_name_and_version (const gchar *name,
+ const gchar *version);
GLIB_AVAILABLE_IN_ALL
GType g_type_parent (GType type);
GLIB_AVAILABLE_IN_ALL
@@ -1938,6 +1945,12 @@ static void type_name##_class_intern_init (gpointer klass) \
}
#endif /* GLIB_VERSION_MAX_ALLOWED >= GLIB_VERSION_2_38 */
+#ifdef G_DEFINE_TYPE_DEFAULT_VERSION
+#define G_TYPE_GET_VERSIONED_NAME(TypeName) #TypeName "@@" G_STRINGIFY(G_DEFINE_TYPE_DEFAULT_VERSION)
+#else
+#define G_TYPE_GET_VERSIONED_NAME(TypeName) #TypeName
+#endif
+
#define _G_DEFINE_TYPE_EXTENDED_BEGIN(TypeName, type_name, TYPE_PARENT, flags) \
\
static void type_name##_init (TypeName *self); \
@@ -1962,7 +1975,7 @@ type_name##_get_type (void) \
{ \
GType g_define_type_id = \
g_type_register_static_simple (TYPE_PARENT, \
- g_intern_static_string (#TypeName), \
+ g_intern_static_string (G_TYPE_GET_VERSIONED_NAME(TypeName)), \
sizeof (TypeName##Class), \
(GClassInitFunc) type_name##_class_intern_init, \
sizeof (TypeName), \
@@ -1989,7 +2002,7 @@ type_name##_get_type (void) \
{ \
GType g_define_type_id = \
g_type_register_static_simple (G_TYPE_INTERFACE, \
- g_intern_static_string (#TypeName), \
+ g_intern_static_string (G_TYPE_GET_VERSIONED_NAME(TypeName)), \
sizeof (TypeName##Interface), \
(GClassInitFunc)type_name##_default_init, \
0, \
@@ -2074,7 +2087,7 @@ type_name##_get_type (void) \
} __attribute__((__transparent_union__)) \
) = g_boxed_type_register_static; \
GType g_define_type_id = \
- _g_register_boxed (g_intern_static_string (#TypeName), copy_func, free_func); \
+ _g_register_boxed (g_intern_static_string (G_TYPE_GET_VERSIONED_NAME(TypeName)), copy_func, free_func); \
{ /* custom code follows */
#else
#define _G_DEFINE_BOXED_TYPE_BEGIN(TypeName, type_name, copy_func, free_func) \
@@ -2085,7 +2098,7 @@ type_name##_get_type (void) \
if (g_once_init_enter (&g_define_type_id__volatile)) \
{ \
GType g_define_type_id = \
- g_boxed_type_register_static (g_intern_static_string (#TypeName), \
+ g_boxed_type_register_static (g_intern_static_string (G_TYPE_GET_VERSIONED_NAME(TypeName)), \
(GBoxedCopyFunc) copy_func, \
(GBoxedFreeFunc) free_func); \
{ /* custom code follows */
@@ -2126,7 +2139,7 @@ type_name##_get_type (void) \
if (g_once_init_enter (&g_define_type_id__volatile)) \
{ \
GType g_define_type_id = \
- g_pointer_type_register_static (g_intern_static_string (#TypeName)); \
+ g_pointer_type_register_static (g_intern_static_string (G_TYPE_GET_VERSIONED_NAME(TypeName))); \
{ /* custom code follows */
/* --- protected (for fundamental type implementations) --- */