[pygobject: 2/3] gi/pygtype.c: avoid GIL congestion in pyg_type_lookup
- From: Christoph Reiter <creiter src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [pygobject: 2/3] gi/pygtype.c: avoid GIL congestion in pyg_type_lookup
- Date: Sun, 18 Feb 2018 08:32:57 +0000 (UTC)
commit aab23dbdb38c5c316c1939410e0301aa8b262143
Author: Mikhail Fludkov <fludkov me gmail com>
Date: Wed Feb 7 16:03:42 2018 +0100
gi/pygtype.c: avoid GIL congestion in pyg_type_lookup
https://gitlab.gnome.org/GNOME/pygobject/issues/123
GIL congestion can be caused when many threads emit signals with objects of
boxed type up to Python. The code in pyg_type_lookup imports a python module
corresponding to gtype, which is expensive and can cause GIL congestion. What
the proposed patch of pyg_type_lookup does:
- pygi_type_import_by_g_type is called only once per a gtype
- early NULL return. For example GStreamer types benefit greatly from it.
Because pyg_register_gtype_custom is not used and pyg_type_lookup always
returns NULL for such types.
gi/pygtype.c | 41 ++++++++++++++++++++++++++++++++++++-----
1 file changed, 36 insertions(+), 5 deletions(-)
---
diff --git a/gi/pygtype.c b/gi/pygtype.c
index 85a6d829..760af56a 100644
--- a/gi/pygtype.c
+++ b/gi/pygtype.c
@@ -618,6 +618,14 @@ pyg_flags_get_value(GType flag_type, PyObject *obj, guint *val)
}
static GQuark pyg_type_marshal_key = 0;
+static GQuark pyg_type_marshal_helper_key = 0;
+
+typedef enum _marshal_helper_data_e marshal_helper_data_e;
+enum _marshal_helper_data_e {
+ MARSHAL_HELPER_NONE = 0,
+ MARSHAL_HELPER_RETURN_NULL,
+ MARSHAL_HELPER_IMPORT_DONE,
+};
PyGTypeMarshal *
pyg_type_lookup(GType type)
@@ -625,12 +633,33 @@ pyg_type_lookup(GType type)
GType ptype = type;
PyGTypeMarshal *tm = NULL;
- /* recursively lookup types */
- while (ptype) {
- pygi_type_import_by_g_type (ptype);
+ if (type == G_TYPE_INVALID)
+ return NULL;
+
+ marshal_helper_data_e marshal_helper = GPOINTER_TO_INT (
+ g_type_get_qdata(type, pyg_type_marshal_helper_key));
+
+ /* If we called this function before with @type and nothing was found,
+ * return NULL early to not spend time in the loop below */
+ if (marshal_helper == MARSHAL_HELPER_RETURN_NULL)
+ return NULL;
+
+ /* Otherwise do recursive type lookup */
+ do {
+ if (marshal_helper == MARSHAL_HELPER_IMPORT_DONE)
+ pygi_type_import_by_g_type (ptype);
+
if ((tm = g_type_get_qdata(ptype, pyg_type_marshal_key)) != NULL)
break;
ptype = g_type_parent(ptype);
+ } while (ptype);
+
+ if (marshal_helper == MARSHAL_HELPER_NONE) {
+ marshal_helper = (tm == NULL) ?
+ MARSHAL_HELPER_RETURN_NULL:
+ MARSHAL_HELPER_IMPORT_DONE;
+ g_type_set_qdata(type, pyg_type_marshal_helper_key,
+ GINT_TO_POINTER(marshal_helper));
}
return tm;
}
@@ -653,8 +682,10 @@ pyg_register_gtype_custom(GType gtype,
{
PyGTypeMarshal *tm;
- if (!pyg_type_marshal_key)
- pyg_type_marshal_key = g_quark_from_static_string("PyGType::marshal");
+ if (!pyg_type_marshal_key) {
+ pyg_type_marshal_key = g_quark_from_static_string("PyGType::marshal");
+ pyg_type_marshal_helper_key = g_quark_from_static_string("PyGType::marshal-helper");
+ }
tm = g_new(PyGTypeMarshal, 1);
tm->fromvalue = from_func;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]