Commit 017f78d7 authored by Colin Walters's avatar Colin Walters

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
parent ac0b0c84
......@@ -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)
......
......@@ -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
......
......@@ -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); \
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment