diff options
author | Christoph Reiter <reiter.christoph@gmail.com> | 2018-02-18 08:32:22 +0000 |
---|---|---|
committer | Christoph Reiter <reiter.christoph@gmail.com> | 2018-02-18 08:32:22 +0000 |
commit | d3cd49ce8777312cbb91b82bd076c0e4b761c848 (patch) | |
tree | 7607c5980668be21d4236616d4dd0ff447f6e01b | |
parent | 5ec1aea8ab4599a7a0945bd5754ce79c7c5cbef3 (diff) | |
parent | aab23dbdb38c5c316c1939410e0301aa8b262143 (diff) | |
download | pygobject-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.c | 2 | ||||
-rw-r--r-- | gi/pygi-info.c | 2 | ||||
-rw-r--r-- | gi/pygi-type.c | 2 | ||||
-rw-r--r-- | gi/pyglib-python-compat.h | 17 | ||||
-rw-r--r-- | gi/pygtype.c | 41 |
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; |