summaryrefslogtreecommitdiff
path: root/gi/pygi-invoke.c
diff options
context:
space:
mode:
authorDongHun Kwak <dh0128.kwak@samsung.com>2017-07-12 08:35:52 +0900
committerDongHun Kwak <dh0128.kwak@samsung.com>2017-07-12 08:35:52 +0900
commitc79482ebfe55da780fd2d733696f5107dc4d5cb8 (patch)
tree8411f3b719fb7caa88160b97cf5f00802a717cec /gi/pygi-invoke.c
parentee96b8b4ed303ec374e37237f86555754cf2ae60 (diff)
downloadpygobject2-c79482ebfe55da780fd2d733696f5107dc4d5cb8.tar.gz
pygobject2-c79482ebfe55da780fd2d733696f5107dc4d5cb8.tar.bz2
pygobject2-c79482ebfe55da780fd2d733696f5107dc4d5cb8.zip
Imported Upstream version 2.27.91
Change-Id: I3788dba2f5257cabaed71dd66932f46025d61a4e Signed-off-by: DongHun Kwak <dh0128.kwak@samsung.com>
Diffstat (limited to 'gi/pygi-invoke.c')
-rw-r--r--gi/pygi-invoke.c54
1 files changed, 50 insertions, 4 deletions
diff --git a/gi/pygi-invoke.c b/gi/pygi-invoke.c
index c93442a..78984e5 100644
--- a/gi/pygi-invoke.c
+++ b/gi/pygi-invoke.c
@@ -62,6 +62,12 @@ struct invocation_state
PyObject *return_value;
GType implementor_gtype;
+
+ /* hack to avoid treating C arrays as GArrays during free
+ * due to overly complicated array handling
+ * this will be removed when the new invoke branch is merged
+ */
+ gboolean c_arrays_are_wrapped;
};
static gboolean
@@ -121,6 +127,11 @@ _initialize_invocation_state (struct invocation_state *state,
state->out_values = NULL;
state->backup_args = NULL;
+ /* HACK: this gets marked FALSE whenever a C array in the args is
+ * not wrapped by a GArray
+ */
+ state->c_arrays_are_wrapped = TRUE;
+
return TRUE;
}
@@ -556,6 +567,20 @@ _prepare_invocation_state (struct invocation_state *state,
(g_type_info_get_array_type (state->arg_type_infos[i]) == GI_ARRAY_TYPE_C)) {
state->args[i]->v_pointer = array->data;
+ /* HACK: We have unwrapped a C array so
+ * set the state to reflect this.
+ * If there is an error between now
+ * and when we rewrap the array
+ * we will leak C arrays due to
+ * being in an inconsitant state.
+ * e.g. for interfaces with more
+ * than one C array argument, an
+ * error may occure when not all
+ * C arrays have been rewrapped.
+ * This will be removed once the invoke
+ * rewrite branch is merged.
+ */
+ state->c_arrays_are_wrapped = FALSE;
if (direction != GI_DIRECTION_INOUT || transfer != GI_TRANSFER_NOTHING) {
/* The array hasn't been referenced anywhere, so free it to avoid losing memory. */
g_array_free (array, FALSE);
@@ -851,6 +876,14 @@ _process_invocation_state (struct invocation_state *state,
}
+ /* HACK: We rewrapped any C arrays above in a GArray so they are ok to
+ * free as GArrays. We will always leak C arrays if there is
+ * an error before we reach this state as there is no easy way
+ * to know which arrays were wrapped if there are more than one.
+ * This will be removed with better array handling once merge
+ * the invoke rewrite branch.
+ */
+ state->c_arrays_are_wrapped = TRUE;
g_assert (state->n_return_values <= 1 || return_values_pos == state->n_return_values);
}
@@ -900,13 +933,26 @@ _free_invocation_state (struct invocation_state *state)
backup_args_pos += 1;
}
if (state->args != NULL && state->args[i] != NULL) {
- _pygi_argument_release (state->args[i], state->arg_type_infos[i],
- transfer, direction);
-
type_tag = g_type_info_get_tag (state->arg_type_infos[i]);
+
+ if (type_tag == GI_TYPE_TAG_ARRAY &&
+ (direction == GI_DIRECTION_IN || direction == GI_DIRECTION_INOUT) &&
+ (g_type_info_get_array_type (state->arg_type_infos[i]) == GI_ARRAY_TYPE_C) &&
+ !state->c_arrays_are_wrapped) {
+ /* HACK: Noop - we are in an inconsitant state due to
+ * complex array handler so leak any C arrays
+ * as we don't know if we can free them safely.
+ * This will be removed when we merge the
+ * invoke rewrite branch.
+ */
+ } else {
+ _pygi_argument_release (state->args[i], state->arg_type_infos[i],
+ transfer, direction);
+ }
+
if (type_tag == GI_TYPE_TAG_ARRAY
&& (direction != GI_DIRECTION_IN && transfer == GI_TRANSFER_NOTHING)) {
- /* We created a #GArray and it has not been released above, so free it. */
+ /* We created an *out* #GArray and it has not been released above, so free it. */
state->args[i]->v_pointer = g_array_free (state->args[i]->v_pointer, FALSE);
}
}