[glib] gtype: Add private DEFINE_TYPE with prelude to workaround gtype deadlocks
- From: Colin Walters <walters src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glib] gtype: Add private DEFINE_TYPE with prelude to workaround gtype deadlocks
- Date: Wed, 14 Jun 2017 18:46:11 +0000 (UTC)
commit 017f78d77f0bf2bed749e21199ea89d75e56ab69
Author: Colin Walters <walters verbum org>
Date: Fri May 19 15:54:39 2017 -0400
gtype: Add private DEFINE_TYPE with prelude to workaround gtype deadlocks
And use it in GSocket, as it had a real-world case reported.
https://bugzilla.gnome.org/show_bug.cgi?id=674885
gio/gsocket.c | 24 +++++++++++++++++-------
gobject/gtype-private.h | 11 +++++++++++
gobject/gtype.h | 16 ++++++++++++++--
3 files changed, 42 insertions(+), 9 deletions(-)
---
diff --git a/gio/gsocket.c b/gio/gsocket.c
index 2f04055..248074a 100644
--- a/gio/gsocket.c
+++ b/gio/gsocket.c
@@ -52,6 +52,9 @@
#include <sys/uio.h>
#endif
+#define GOBJECT_COMPILATION
+#include "gobject/gtype-private.h" /* For _PRELUDE type define */
+#undef GOBJECT_COMPILATION
#include "gcancellable.h"
#include "gdatagrambased.h"
#include "gioenumtypes.h"
@@ -267,13 +270,20 @@ struct _GSocketPrivate
} recv_addr_cache[RECV_ADDR_CACHE_SIZE];
};
-G_DEFINE_TYPE_WITH_CODE (GSocket, g_socket, G_TYPE_OBJECT,
- G_ADD_PRIVATE (GSocket)
- g_networking_init ();
- G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE,
- g_socket_initable_iface_init);
- G_IMPLEMENT_INTERFACE (G_TYPE_DATAGRAM_BASED,
- g_socket_datagram_based_iface_init));
+_G_DEFINE_TYPE_EXTENDED_WITH_PRELUDE (GSocket, g_socket, G_TYPE_OBJECT, 0,
+ /* Need a prelude for
https://bugzilla.gnome.org/show_bug.cgi?id=674885 */
+ g_type_ensure (G_TYPE_SOCKET_FAMILY);
+ g_type_ensure (G_TYPE_SOCKET_TYPE);
+ g_type_ensure (G_TYPE_SOCKET_PROTOCOL);
+ g_type_ensure (G_TYPE_SOCKET_ADDRESS);
+ /* And networking init is appropriate for the prelude */
+ g_networking_init ();
+ , /* And now the regular type init code */
+ G_ADD_PRIVATE (GSocket)
+ G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE,
+ g_socket_initable_iface_init);
+ G_IMPLEMENT_INTERFACE (G_TYPE_DATAGRAM_BASED,
+ g_socket_datagram_based_iface_init));
static int
get_socket_errno (void)
diff --git a/gobject/gtype-private.h b/gobject/gtype-private.h
index 1d05755..5f2f13b 100644
--- a/gobject/gtype-private.h
+++ b/gobject/gtype-private.h
@@ -90,6 +90,17 @@ void _g_closure_invoke_va (GClosure *closure,
int n_params,
GType *param_types);
+/**
+ * _G_DEFINE_TYPE_EXTENDED_WITH_PRELUDE:
+ *
+ * See also G_DEFINE_TYPE_EXTENDED(). This macro is generally only
+ * necessary as a workaround for classes which have properties of
+ * object types that may be initialized in distinct threads. See:
+ * https://bugzilla.gnome.org/show_bug.cgi?id=674885
+ *
+ * Currently private.
+ */
+#define _G_DEFINE_TYPE_EXTENDED_WITH_PRELUDE(TN, t_n, T_P, _f_, _P_, _C_)
_G_DEFINE_TYPE_EXTENDED_BEGIN_PRE (TN, t_n, T_P) {_P_;} _G_DEFINE_TYPE_EXTENDED_BEGIN_REGISTER (TN, t_n, T_P,
_f_){_C_;} _G_DEFINE_TYPE_EXTENDED_END()
G_END_DECLS
diff --git a/gobject/gtype.h b/gobject/gtype.h
index ab8f97c..89c1bec 100644
--- a/gobject/gtype.h
+++ b/gobject/gtype.h
@@ -1943,7 +1943,8 @@ static void type_name##_class_intern_init (gpointer klass) \
}
#endif /* GLIB_VERSION_MAX_ALLOWED >= GLIB_VERSION_2_38 */
-#define _G_DEFINE_TYPE_EXTENDED_BEGIN(TypeName, type_name, TYPE_PARENT, flags) \
+/* Added for _G_DEFINE_TYPE_EXTENDED_WITH_PRELUDE */
+#define _G_DEFINE_TYPE_EXTENDED_BEGIN_PRE(TypeName, type_name, TYPE_PARENT) \
\
static void type_name##_init (TypeName *self); \
static void type_name##_class_init (TypeName##Class *klass); \
@@ -1962,7 +1963,11 @@ type_name##_get_instance_private (TypeName *self) \
GType \
type_name##_get_type (void) \
{ \
- static volatile gsize g_define_type_id__volatile = 0; \
+ static volatile gsize g_define_type_id__volatile = 0;
+ /* Prelude goes here */
+
+/* Added for _G_DEFINE_TYPE_EXTENDED_WITH_PRELUDE */
+#define _G_DEFINE_TYPE_EXTENDED_BEGIN_REGISTER(TypeName, type_name, TYPE_PARENT, flags) \
if (g_once_init_enter (&g_define_type_id__volatile)) \
{ \
GType g_define_type_id = \
@@ -1982,6 +1987,13 @@ type_name##_get_type (void) \
return g_define_type_id__volatile; \
} /* closes type_name##_get_type() */
+/* This was defined before we had G_DEFINE_TYPE_WITH_CODE_AND_PRELUDE, it's simplest
+ * to keep it.
+ */
+#define _G_DEFINE_TYPE_EXTENDED_BEGIN(TypeName, type_name, TYPE_PARENT, flags) \
+ _G_DEFINE_TYPE_EXTENDED_BEGIN_PRE(TypeName, type_name, TYPE_PARENT) \
+ _G_DEFINE_TYPE_EXTENDED_BEGIN_REGISTER(TypeName, type_name, TYPE_PARENT, flags) \
+
#define _G_DEFINE_INTERFACE_EXTENDED_BEGIN(TypeName, type_name, TYPE_PREREQ) \
\
static void type_name##_default_init (TypeName##Interface *klass); \
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]