summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristoph Reiter <reiter.christoph@gmail.com>2018-02-18 08:32:22 +0000
committerChristoph Reiter <reiter.christoph@gmail.com>2018-02-18 08:32:22 +0000
commitd3cd49ce8777312cbb91b82bd076c0e4b761c848 (patch)
tree7607c5980668be21d4236616d4dd0ff447f6e01b
parent5ec1aea8ab4599a7a0945bd5754ce79c7c5cbef3 (diff)
parentaab23dbdb38c5c316c1939410e0301aa8b262143 (diff)
downloadpygobject-d3cd49ce8777312cbb91b82bd076c0e4b761c848.tar.gz
Merge branch 'gilabissue123' into 'master'
Performance improvements to avoid GIL congestion See merge request GNOME/pygobject!13
-rw-r--r--gi/pygi-error.c2
-rw-r--r--gi/pygi-info.c2
-rw-r--r--gi/pygi-type.c2
-rw-r--r--gi/pyglib-python-compat.h17
-rw-r--r--gi/pygtype.c41
5 files changed, 56 insertions, 8 deletions
diff --git a/gi/pygi-error.c b/gi/pygi-error.c
index 4827e9f4..26391411 100644
--- a/gi/pygi-error.c
+++ b/gi/pygi-error.c
@@ -376,7 +376,7 @@ pygerror_to_gvalue (GValue *value, PyObject *pyerror)
void
pygi_error_register_types (PyObject *module)
{
- PyObject *error_module = PyImport_ImportModule ("gi._error");
+ PyObject *error_module = PYGLIB_PyImport_ImportModule ("gi._error");
if (!error_module) {
return;
}
diff --git a/gi/pygi-info.c b/gi/pygi-info.c
index 1b33e9a7..e46f6007 100644
--- a/gi/pygi-info.c
+++ b/gi/pygi-info.c
@@ -41,7 +41,7 @@ _generate_doc_string(PyGIBaseInfo *self)
static PyObject *_py_generate_doc_string = NULL;
if (_py_generate_doc_string == NULL) {
- PyObject *mod = PyImport_ImportModule ("gi.docstring");
+ PyObject *mod = PYGLIB_PyImport_ImportModule ("gi.docstring");
if (!mod)
return NULL;
diff --git a/gi/pygi-type.c b/gi/pygi-type.c
index 06d773a3..9561c432 100644
--- a/gi/pygi-type.c
+++ b/gi/pygi-type.c
@@ -35,7 +35,7 @@ _pygi_type_import_by_name (const char *namespace_,
module_name = g_strconcat ("gi.repository.", namespace_, NULL);
- py_module = PyImport_ImportModule (module_name);
+ py_module = PYGLIB_PyImport_ImportModule (module_name);
g_free (module_name);
diff --git a/gi/pyglib-python-compat.h b/gi/pyglib-python-compat.h
index d6f7553f..b1f4b222 100644
--- a/gi/pyglib-python-compat.h
+++ b/gi/pyglib-python-compat.h
@@ -115,6 +115,21 @@ PyTypeObject symbol = { \
return; \
PyDict_SetItemString(d, name, (PyObject *)&type);
+/* Better alternative to PyImport_ImportModule which tries to import from
+ * sys.modules first */
+static inline PyObject *
+PYGLIB_PyImport_ImportModule(const char *name)
+{
+ /* see PyImport_ImportModuleNoBlock
+ * https://github.com/python/cpython/blob/2.7/Python/import.c#L2166-L2206 */
+ PyObject *result = PyImport_ImportModuleNoBlock(name);
+ if (result)
+ return result;
+
+ PyErr_Clear();
+ return PyImport_ImportModule(name);
+}
+
#else
#define PYGLIB_MODULE_START(symbol, modname) \
@@ -157,6 +172,8 @@ PyTypeObject symbol = { \
return; \
PyDict_SetItemString(d, name, (PyObject *)&type);
+#define PYGLIB_PyImport_ImportModule PyImport_ImportModule
+
#define PYGLIB_PyBaseString_Check PyUnicode_Check
#define PYGLIB_PyUnicode_Check PyUnicode_Check
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;