mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-03-03 22:52:09 +01:00
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
This commit is contained in:
parent
ac0b0c84f7
commit
017f78d77f
@ -52,6 +52,9 @@
|
|||||||
#include <sys/uio.h>
|
#include <sys/uio.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define GOBJECT_COMPILATION
|
||||||
|
#include "gobject/gtype-private.h" /* For _PRELUDE type define */
|
||||||
|
#undef GOBJECT_COMPILATION
|
||||||
#include "gcancellable.h"
|
#include "gcancellable.h"
|
||||||
#include "gdatagrambased.h"
|
#include "gdatagrambased.h"
|
||||||
#include "gioenumtypes.h"
|
#include "gioenumtypes.h"
|
||||||
@ -267,9 +270,16 @@ struct _GSocketPrivate
|
|||||||
} recv_addr_cache[RECV_ADDR_CACHE_SIZE];
|
} recv_addr_cache[RECV_ADDR_CACHE_SIZE];
|
||||||
};
|
};
|
||||||
|
|
||||||
G_DEFINE_TYPE_WITH_CODE (GSocket, g_socket, G_TYPE_OBJECT,
|
_G_DEFINE_TYPE_EXTENDED_WITH_PRELUDE (GSocket, g_socket, G_TYPE_OBJECT, 0,
|
||||||
G_ADD_PRIVATE (GSocket)
|
/* 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 ();
|
g_networking_init ();
|
||||||
|
, /* And now the regular type init code */
|
||||||
|
G_ADD_PRIVATE (GSocket)
|
||||||
G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE,
|
G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE,
|
||||||
g_socket_initable_iface_init);
|
g_socket_initable_iface_init);
|
||||||
G_IMPLEMENT_INTERFACE (G_TYPE_DATAGRAM_BASED,
|
G_IMPLEMENT_INTERFACE (G_TYPE_DATAGRAM_BASED,
|
||||||
|
@ -90,6 +90,17 @@ void _g_closure_invoke_va (GClosure *closure,
|
|||||||
int n_params,
|
int n_params,
|
||||||
GType *param_types);
|
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
|
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 */
|
#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##_init (TypeName *self); \
|
||||||
static void type_name##_class_init (TypeName##Class *klass); \
|
static void type_name##_class_init (TypeName##Class *klass); \
|
||||||
@ -1962,7 +1963,11 @@ type_name##_get_instance_private (TypeName *self) \
|
|||||||
GType \
|
GType \
|
||||||
type_name##_get_type (void) \
|
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)) \
|
if (g_once_init_enter (&g_define_type_id__volatile)) \
|
||||||
{ \
|
{ \
|
||||||
GType g_define_type_id = \
|
GType g_define_type_id = \
|
||||||
@ -1982,6 +1987,13 @@ type_name##_get_type (void) \
|
|||||||
return g_define_type_id__volatile; \
|
return g_define_type_id__volatile; \
|
||||||
} /* closes type_name##_get_type() */
|
} /* 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) \
|
#define _G_DEFINE_INTERFACE_EXTENDED_BEGIN(TypeName, type_name, TYPE_PREREQ) \
|
||||||
\
|
\
|
||||||
static void type_name##_default_init (TypeName##Interface *klass); \
|
static void type_name##_default_init (TypeName##Interface *klass); \
|
||||||
|
Loading…
x
Reference in New Issue
Block a user