[pygobject] Prevent passing the user data multiple times to callbacks
- From: Garrett Regier <gregier src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [pygobject] Prevent passing the user data multiple times to callbacks
- Date: Tue, 22 Sep 2015 21:47:02 +0000 (UTC)
commit 3066f3a88103f02c7e22db22efbeb501f4e30d32
Author: Garrett Regier <garrett regier riftio com>
Date: Wed Jun 3 07:50:37 2015 -0700
Prevent passing the user data multiple times to callbacks
This can happen when a callback has multiple gpointers.
Also, store the closure index as it is hopefully more reliable
than guessing.
https://bugzilla.gnome.org/show_bug.cgi?id=750347
gi/pygi-cache.c | 24 ++++++++++++++++++++++++
gi/pygi-cache.h | 3 +++
gi/pygi-closure.c | 8 ++------
3 files changed, 29 insertions(+), 6 deletions(-)
---
diff --git a/gi/pygi-cache.c b/gi/pygi-cache.c
index ca24517..84cc463 100644
--- a/gi/pygi-cache.c
+++ b/gi/pygi-cache.c
@@ -489,6 +489,8 @@ _callable_cache_generate_args_cache_real (PyGICallableCache *callable_cache,
callable_cache->return_cache = return_cache;
g_base_info_unref (return_info);
+ callable_cache->user_data_index = -1;
+
for (i = 0, arg_index = callable_cache->args_offset;
arg_index < _pygi_callable_cache_args_len (callable_cache);
i++, arg_index++) {
@@ -498,7 +500,9 @@ _callable_cache_generate_args_cache_real (PyGICallableCache *callable_cache,
arg_info = g_callable_info_get_arg (callable_info, i);
+ /* This only happens when dealing with callbacks */
if (g_arg_info_get_closure (arg_info) == i) {
+ callable_cache->user_data_index = i;
arg_cache = pygi_arg_cache_alloc ();
_pygi_callable_cache_set_arg (callable_cache, arg_index, arg_cache);
@@ -1116,6 +1120,26 @@ pygi_closure_cache_new (GICallableInfo *info)
len_arg_cache->meta_type = PYGI_META_ARG_TYPE_PARENT;
}
+ /* Prevent guessing multiple user data arguments.
+ * This is required because some versions of GI
+ * do not recognize user_data/data arguments correctly.
+ */
+ if (callable_cache->user_data_index == -1) {
+ for (i = 0; i < _pygi_callable_cache_args_len (callable_cache); i++) {
+ PyGIArgCache *arg_cache;
+
+ arg_cache = g_ptr_array_index (callable_cache->args_cache, i);
+
+ if (arg_cache->direction == PYGI_DIRECTION_TO_PYTHON &&
+ arg_cache->type_tag == GI_TYPE_TAG_VOID &&
+ arg_cache->is_pointer) {
+
+ callable_cache->user_data_index = i;
+ break;
+ }
+ }
+ }
+
return closure_cache;
}
diff --git a/gi/pygi-cache.h b/gi/pygi-cache.h
index 098f3f1..ad41755 100644
--- a/gi/pygi-cache.h
+++ b/gi/pygi-cache.h
@@ -170,6 +170,9 @@ struct _PyGICallableCache
GHashTable *arg_name_hash;
gboolean throws;
+ /* Index of user_data arg passed to a callable. */
+ gssize user_data_index;
+
/* Index of user_data arg that can eat variable args passed to a callable. */
gssize user_data_varargs_index;
diff --git a/gi/pygi-closure.c b/gi/pygi-closure.c
index 1655499..b239777 100644
--- a/gi/pygi-closure.c
+++ b/gi/pygi-closure.c
@@ -370,17 +370,13 @@ _pygi_closure_convert_arguments (PyGIInvokeState *state,
for (i = 0; i < _pygi_callable_cache_args_len (cache); i++) {
PyGIArgCache *arg_cache;
- PyGIDirection direction;
arg_cache = g_ptr_array_index (cache->args_cache, i);
- direction = arg_cache->direction;
- if (direction & PYGI_DIRECTION_TO_PYTHON) {
+ if (arg_cache->direction & PYGI_DIRECTION_TO_PYTHON) {
PyObject *value;
- if (direction == PYGI_DIRECTION_TO_PYTHON &&
- arg_cache->type_tag == GI_TYPE_TAG_VOID &&
- arg_cache->is_pointer) {
+ if (cache->user_data_index == i) {
if (state->user_data == NULL) {
/* user_data can be NULL for connect functions which don't accept
* user_data or as the default for user_data in the middle of function
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]