1 /* -*- Mode: C; c-basic-offset: 4 -*-
2 * vim: tabstop=4 shiftwidth=4 expandtab
4 * pygi-closure.c: PyGI C Closure functions
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
20 #include "pygi-closure.h"
21 #include "pygi-error.h"
22 #include "pygi-marshal-cleanup.h"
23 #include "pygi-invoke.h"
24 #include "pygi-ccallback.h"
25 #include "pygi-info.h"
27 extern PyObject *_PyGIDefaultArgPlaceholder;
29 typedef struct _PyGICallbackCache
31 PyGIArgCache arg_cache;
32 gssize user_data_index;
33 gssize destroy_notify_index;
35 GIInterfaceInfo *interface_info;
38 /* This maintains a list of closures which can be free'd whenever
39 as they have been called. We will free them on the next
40 library function call.
42 static GSList* async_free_list;
45 _pygi_closure_assign_pyobj_to_retval (gpointer retval,
47 PyGIArgCache *arg_cache)
52 switch (arg_cache->type_tag) {
53 case GI_TYPE_TAG_BOOLEAN:
54 *((ffi_sarg *) retval) = arg->v_boolean;
56 case GI_TYPE_TAG_INT8:
57 *((ffi_sarg *) retval) = arg->v_int8;
59 case GI_TYPE_TAG_UINT8:
60 *((ffi_arg *) retval) = arg->v_uint8;
62 case GI_TYPE_TAG_INT16:
63 *((ffi_sarg *) retval) = arg->v_int16;
65 case GI_TYPE_TAG_UINT16:
66 *((ffi_arg *) retval) = arg->v_uint16;
68 case GI_TYPE_TAG_INT32:
69 *((ffi_sarg *) retval) = arg->v_int32;
71 case GI_TYPE_TAG_UINT32:
72 *((ffi_arg *) retval) = arg->v_uint32;
74 case GI_TYPE_TAG_INT64:
75 *((ffi_sarg *) retval) = arg->v_int64;
77 case GI_TYPE_TAG_UINT64:
78 *((ffi_arg *) retval) = arg->v_uint64;
80 case GI_TYPE_TAG_FLOAT:
81 *((gfloat *) retval) = arg->v_float;
83 case GI_TYPE_TAG_DOUBLE:
84 *((gdouble *) retval) = arg->v_double;
86 case GI_TYPE_TAG_GTYPE:
87 *((ffi_arg *) retval) = arg->v_ulong;
89 case GI_TYPE_TAG_UNICHAR:
90 *((ffi_arg *) retval) = arg->v_uint32;
92 case GI_TYPE_TAG_INTERFACE:
94 GIBaseInfo *interface_info;
96 interface_info = ((PyGIInterfaceCache *) arg_cache)->interface_info;
98 switch (g_base_info_get_type (interface_info)) {
99 case GI_INFO_TYPE_ENUM:
100 *(ffi_sarg *) retval = arg->v_int;
102 case GI_INFO_TYPE_FLAGS:
103 *(ffi_arg *) retval = arg->v_uint;
106 *(ffi_arg *) retval = (ffi_arg) arg->v_pointer;
113 *(ffi_arg *) retval = (ffi_arg) arg->v_pointer;
119 _pygi_closure_assign_pyobj_to_out_argument (gpointer out_arg,
121 PyGIArgCache *arg_cache)
126 switch (arg_cache->type_tag) {
127 case GI_TYPE_TAG_BOOLEAN:
128 *((gboolean *) out_arg) = arg->v_boolean;
130 case GI_TYPE_TAG_INT8:
131 *((gint8 *) out_arg) = arg->v_int8;
133 case GI_TYPE_TAG_UINT8:
134 *((guint8 *) out_arg) = arg->v_uint8;
136 case GI_TYPE_TAG_INT16:
137 *((gint16 *) out_arg) = arg->v_int16;
139 case GI_TYPE_TAG_UINT16:
140 *((guint16 *) out_arg) = arg->v_uint16;
142 case GI_TYPE_TAG_INT32:
143 *((gint32 *) out_arg) = arg->v_int32;
145 case GI_TYPE_TAG_UINT32:
146 *((guint32 *) out_arg) = arg->v_uint32;
148 case GI_TYPE_TAG_INT64:
149 *((gint64 *) out_arg) = arg->v_int64;
151 case GI_TYPE_TAG_UINT64:
152 *((glong *) out_arg) = arg->v_uint64;
154 case GI_TYPE_TAG_FLOAT:
155 *((gfloat *) out_arg) = arg->v_float;
157 case GI_TYPE_TAG_DOUBLE:
158 *((gdouble *) out_arg) = arg->v_double;
160 case GI_TYPE_TAG_GTYPE:
161 *((gulong *) out_arg) = arg->v_ulong;
163 case GI_TYPE_TAG_UNICHAR:
164 *((guint32 *) out_arg) = arg->v_uint32;
166 case GI_TYPE_TAG_INTERFACE:
168 GIBaseInfo *interface_info;
170 interface_info = ((PyGIInterfaceCache *) arg_cache)->interface_info;
172 switch (g_base_info_get_type (interface_info)) {
173 case GI_INFO_TYPE_ENUM:
174 *(gint *) out_arg = arg->v_int;
176 case GI_INFO_TYPE_FLAGS:
177 *(guint *) out_arg = arg->v_uint;
179 case GI_INFO_TYPE_STRUCT:
180 if (!arg_cache->is_pointer) {
181 if (arg->v_pointer != NULL) {
182 gsize item_size = _pygi_g_type_info_size (arg_cache->type_info);
183 memcpy (out_arg, arg->v_pointer, item_size);
188 /* Fall through if pointer */
190 *((gpointer *) out_arg) = arg->v_pointer;
197 *((gpointer *) out_arg) = arg->v_pointer;
203 _pygi_closure_convert_ffi_arguments (PyGIInvokeArgState *state,
204 PyGICallableCache *cache,
209 for (i = 0; i < _pygi_callable_cache_args_len (cache); i++) {
210 PyGIArgCache *arg_cache = g_ptr_array_index (cache->args_cache, i);
212 if (arg_cache->direction & PYGI_DIRECTION_FROM_PYTHON) {
213 state[i].arg_value.v_pointer = * (gpointer *) args[i];
215 if (state[i].arg_value.v_pointer == NULL)
218 state[i].arg_pointer.v_pointer = state[i].arg_value.v_pointer;
219 state[i].arg_value = *(GIArgument *) state[i].arg_value.v_pointer;
223 switch (arg_cache->type_tag) {
224 case GI_TYPE_TAG_BOOLEAN:
225 state[i].arg_value.v_boolean = * (gboolean *) args[i];
227 case GI_TYPE_TAG_INT8:
228 state[i].arg_value.v_int8 = * (gint8 *) args[i];
230 case GI_TYPE_TAG_UINT8:
231 state[i].arg_value.v_uint8 = * (guint8 *) args[i];
233 case GI_TYPE_TAG_INT16:
234 state[i].arg_value.v_int16 = * (gint16 *) args[i];
236 case GI_TYPE_TAG_UINT16:
237 state[i].arg_value.v_uint16 = * (guint16 *) args[i];
239 case GI_TYPE_TAG_INT32:
240 state[i].arg_value.v_int32 = * (gint32 *) args[i];
242 case GI_TYPE_TAG_UINT32:
243 state[i].arg_value.v_uint32 = * (guint32 *) args[i];
245 case GI_TYPE_TAG_INT64:
246 state[i].arg_value.v_int64 = * (glong *) args[i];
248 case GI_TYPE_TAG_UINT64:
249 state[i].arg_value.v_uint64 = * (glong *) args[i];
251 case GI_TYPE_TAG_FLOAT:
252 state[i].arg_value.v_float = * (gfloat *) args[i];
254 case GI_TYPE_TAG_DOUBLE:
255 state[i].arg_value.v_double = * (gdouble *) args[i];
257 case GI_TYPE_TAG_UTF8:
258 state[i].arg_value.v_string = * (gchar **) args[i];
260 case GI_TYPE_TAG_INTERFACE:
262 GIBaseInfo *interface;
263 GIInfoType interface_type;
265 interface = ((PyGIInterfaceCache *) arg_cache)->interface_info;
266 interface_type = g_base_info_get_type (interface);
268 if (interface_type == GI_INFO_TYPE_ENUM) {
269 state[i].arg_value.v_int = * (gint *) args[i];
270 } else if (interface_type == GI_INFO_TYPE_FLAGS) {
271 state[i].arg_value.v_uint = * (guint *) args[i];
273 state[i].arg_value.v_pointer = * (gpointer *) args[i];
277 case GI_TYPE_TAG_UNICHAR:
278 state[i].arg_value.v_uint32 = * (guint32 *) args[i];
280 case GI_TYPE_TAG_ERROR:
281 case GI_TYPE_TAG_GHASH:
282 case GI_TYPE_TAG_GLIST:
283 case GI_TYPE_TAG_GSLIST:
284 case GI_TYPE_TAG_ARRAY:
285 case GI_TYPE_TAG_VOID:
286 state[i].arg_value.v_pointer = * (gpointer *) args[i];
289 g_warning ("Unhandled type tag %s",
290 g_type_tag_to_string (arg_cache->type_tag));
291 state[i].arg_value.v_pointer = 0;
296 gssize error_index = _pygi_callable_cache_args_len (cache);
298 state[error_index].arg_value.v_pointer = * (gpointer *) args[error_index];
303 _invoke_state_init_from_cache (PyGIInvokeState *state,
304 PyGIClosureCache *closure_cache,
307 PyGICallableCache *cache = (PyGICallableCache *) closure_cache;
309 state->n_args = _pygi_callable_cache_args_len (cache);
310 state->n_py_in_args = state->n_args;
312 /* Increment after setting the number of Python input args */
317 state->py_in_args = PyTuple_New (state->n_py_in_args);
318 if (state->py_in_args == NULL) {
326 if (!_pygi_invoke_arg_state_init (state)) {
330 state->ffi_args = NULL;
332 _pygi_closure_convert_ffi_arguments (state->args, cache, args);
337 _invoke_state_clear (PyGIInvokeState *state)
339 _pygi_invoke_arg_state_free (state);
340 Py_XDECREF (state->py_in_args);
344 _pygi_closure_convert_arguments (PyGIInvokeState *state,
345 PyGIClosureCache *closure_cache)
347 PyGICallableCache *cache = (PyGICallableCache *) closure_cache;
348 gssize n_in_args = 0;
351 for (i = 0; (gsize)i < _pygi_callable_cache_args_len (cache); i++) {
352 PyGIArgCache *arg_cache;
354 arg_cache = g_ptr_array_index (cache->args_cache, i);
356 if (arg_cache->direction & PYGI_DIRECTION_TO_PYTHON) {
359 if (cache->user_data_index == i) {
360 if (state->user_data == NULL) {
361 /* user_data can be NULL for connect functions which don't accept
362 * user_data or as the default for user_data in the middle of function
368 /* Extend the callbacks args with user_data as variable args. */
369 gssize j, user_data_len;
370 PyObject *py_user_data = state->user_data;
372 if (!PyTuple_Check (py_user_data)) {
373 PyErr_SetString (PyExc_TypeError, "expected tuple for callback user_data");
377 user_data_len = PyTuple_Size (py_user_data);
378 _PyTuple_Resize (&state->py_in_args,
379 state->n_py_in_args + user_data_len - 1);
381 for (j = 0; j < user_data_len; j++, n_in_args++) {
382 value = PyTuple_GetItem (py_user_data, j);
384 PyTuple_SET_ITEM (state->py_in_args, n_in_args, value);
386 /* We can assume user_data args are never going to be inout,
387 * so just continue here.
391 } else if (arg_cache->meta_type != PYGI_META_ARG_TYPE_PARENT) {
394 value = arg_cache->to_py_marshaller (state,
397 &state->args[i].arg_value);
400 pygi_marshal_cleanup_args_to_py_parameter_fail (state,
407 PyTuple_SET_ITEM (state->py_in_args, n_in_args, value);
412 if (_PyTuple_Resize (&state->py_in_args, n_in_args) == -1)
419 _pygi_closure_set_out_arguments (PyGIInvokeState *state,
420 PyGICallableCache *cache,
425 gssize i_py_retval = 0;
428 if (cache->return_cache->type_tag != GI_TYPE_TAG_VOID) {
429 PyObject *item = py_retval;
431 if (PyTuple_Check (py_retval)) {
432 item = PyTuple_GET_ITEM (py_retval, 0);
435 success = cache->return_cache->from_py_marshaller (state,
440 &state->args[0].arg_cleanup_data);
443 pygi_marshal_cleanup_args_return_fail (state,
448 _pygi_closure_assign_pyobj_to_retval (resp, &state->return_arg,
449 cache->return_cache);
453 for (i = 0; (gsize)i < _pygi_callable_cache_args_len (cache); i++) {
454 PyGIArgCache *arg_cache = g_ptr_array_index (cache->args_cache, i);
456 if (arg_cache->direction & PYGI_DIRECTION_FROM_PYTHON) {
457 PyObject *item = py_retval;
459 if (arg_cache->type_tag == GI_TYPE_TAG_ERROR) {
460 * (GError **) state->args[i].arg_pointer.v_pointer = NULL;
464 if (PyTuple_Check (py_retval)) {
465 item = PyTuple_GET_ITEM (py_retval, i_py_retval);
466 } else if (i_py_retval != 0) {
467 pygi_marshal_cleanup_args_to_py_parameter_fail (state,
473 success = arg_cache->from_py_marshaller (state,
477 &state->args[i].arg_value,
478 &state->args[i_py_retval].arg_cleanup_data);
481 pygi_marshal_cleanup_args_to_py_parameter_fail (state,
487 _pygi_closure_assign_pyobj_to_out_argument (state->args[i].arg_pointer.v_pointer,
488 &state->args[i].arg_value, arg_cache);
498 _pygi_closure_clear_retvals (PyGIInvokeState *state,
499 PyGICallableCache *cache,
503 GIArgument arg = { 0, };
505 if (cache->return_cache->type_tag != GI_TYPE_TAG_VOID) {
506 _pygi_closure_assign_pyobj_to_retval (resp, &arg,
507 cache->return_cache);
510 for (i = 0; i < _pygi_callable_cache_args_len (cache); i++) {
511 PyGIArgCache *arg_cache = g_ptr_array_index (cache->args_cache, i);
513 if (arg_cache->direction & PYGI_DIRECTION_FROM_PYTHON) {
514 _pygi_closure_assign_pyobj_to_out_argument (state->args[i].arg_pointer.v_pointer,
520 gssize error_index = state->n_args - 1;
521 GError **error = (GError **) state->args[error_index].arg_value.v_pointer;
524 pygi_gerror_exception_check (error);
530 _pygi_invoke_closure_clear_py_data(PyGICClosure *invoke_closure)
532 PyGILState_STATE state = PyGILState_Ensure();
534 Py_CLEAR (invoke_closure->function);
535 Py_CLEAR (invoke_closure->user_data);
537 PyGILState_Release (state);
541 _pygi_closure_handle (ffi_cif *cif,
546 PyGILState_STATE py_state;
547 PyGICClosure *closure = data;
550 PyGIInvokeState state = { 0, };
552 /* Ignore closures when Python is not initialized. This can happen in cases
553 * where calling Python implemented vfuncs can happen at shutdown time.
554 * See: https://bugzilla.gnome.org/show_bug.cgi?id=722562 */
555 if (!Py_IsInitialized()) {
559 /* Lock the GIL as we are coming into this code without the lock and we
560 may be executing python code */
561 py_state = PyGILState_Ensure ();
563 if (closure->cache == NULL) {
564 closure->cache = pygi_closure_cache_new ((GICallableInfo *) closure->info);
566 if (closure->cache == NULL)
570 state.user_data = closure->user_data;
572 _invoke_state_init_from_cache (&state, closure->cache, args);
574 if (!_pygi_closure_convert_arguments (&state, closure->cache)) {
575 _pygi_closure_clear_retvals (&state, closure->cache, result);
579 retval = PyObject_CallObject ( (PyObject *) closure->function, state.py_in_args);
581 if (retval == NULL) {
582 _pygi_closure_clear_retvals (&state, closure->cache, result);
586 pygi_marshal_cleanup_args_to_py_marshal_success (&state, closure->cache);
587 success = _pygi_closure_set_out_arguments (&state, closure->cache, retval, result);
590 pygi_marshal_cleanup_args_from_py_marshal_success (&state, closure->cache);
591 _pygi_closure_clear_retvals (&state, closure->cache, result);
598 if (PyErr_Occurred ())
601 /* Now that the closure has finished we can make a decision about how
602 to free it. Scope call gets free'd at the end of wrap_g_function_info_invoke.
603 Scope notified will be freed when the notify is called.
604 Scope async closures free only their python data now and the closure later
605 during the next creation of a closure. This minimizes potential ref leaks
606 at least in regards to the python objects.
607 (you can't free the closure you are currently using!)
609 switch (closure->scope) {
610 case GI_SCOPE_TYPE_CALL:
611 case GI_SCOPE_TYPE_NOTIFIED:
613 case GI_SCOPE_TYPE_ASYNC:
614 /* Append this PyGICClosure to a list of closure that we will free
615 after we're done with this function invokation */
616 _pygi_invoke_closure_clear_py_data(closure);
617 async_free_list = g_slist_prepend (async_free_list, closure);
620 g_error ("Invalid scope reached inside %s. Possibly a bad annotation?",
621 g_base_info_get_name (closure->info));
624 _invoke_state_clear (&state);
625 PyGILState_Release (py_state);
628 void _pygi_invoke_closure_free (gpointer data)
630 PyGICClosure* invoke_closure = (PyGICClosure *) data;
632 g_callable_info_free_closure (invoke_closure->info,
633 invoke_closure->closure);
635 if (invoke_closure->info)
636 g_base_info_unref ( (GIBaseInfo*) invoke_closure->info);
638 if (invoke_closure->cache != NULL)
639 pygi_callable_cache_free ((PyGICallableCache *) invoke_closure->cache);
641 _pygi_invoke_closure_clear_py_data(invoke_closure);
643 g_slice_free (PyGICClosure, invoke_closure);
648 _pygi_make_native_closure (GICallableInfo* info,
650 PyObject *py_function,
651 gpointer py_user_data)
653 PyGICClosure *closure;
654 ffi_closure *fficlosure;
656 /* Begin by cleaning up old async functions */
657 g_slist_free_full (async_free_list, (GDestroyNotify) _pygi_invoke_closure_free);
658 async_free_list = NULL;
660 /* Build the closure itself */
661 closure = g_slice_new0 (PyGICClosure);
662 closure->info = (GICallableInfo *) g_base_info_ref ( (GIBaseInfo *) info);
663 closure->function = py_function;
664 closure->user_data = py_user_data;
666 Py_INCREF (py_function);
667 Py_XINCREF (closure->user_data);
670 g_callable_info_prepare_closure (info, &closure->cif, _pygi_closure_handle,
672 closure->closure = fficlosure;
674 /* Give the closure the information it needs to determine when
675 to free itself later */
676 closure->scope = scope;
681 /* _pygi_destroy_notify_dummy:
683 * Dummy method used in the occasion when a method has a GDestroyNotify
684 * argument without user data.
687 _pygi_destroy_notify_dummy (gpointer data) {
691 _pygi_marshal_from_py_interface_callback (PyGIInvokeState *state,
692 PyGICallableCache *callable_cache,
693 PyGIArgCache *arg_cache,
696 gpointer *cleanup_data)
698 GICallableInfo *callable_info;
699 PyGICClosure *closure;
700 PyGIArgCache *user_data_cache = NULL;
701 PyGIArgCache *destroy_cache = NULL;
702 PyGICallbackCache *callback_cache;
703 PyObject *py_user_data = NULL;
705 callback_cache = (PyGICallbackCache *)arg_cache;
707 if (callback_cache->user_data_index > 0) {
708 user_data_cache = _pygi_callable_cache_get_arg (callable_cache, callback_cache->user_data_index);
709 if (user_data_cache->py_arg_index < state->n_py_in_args) {
710 /* py_user_data is a borrowed reference. */
711 py_user_data = PyTuple_GetItem (state->py_in_args, user_data_cache->py_arg_index);
714 /* NULL out user_data if it was not supplied and the default arg placeholder
717 if (py_user_data == _PyGIDefaultArgPlaceholder) {
719 } else if (callable_cache->user_data_varargs_index < 0) {
720 /* For non-variable length user data, place the user data in a
721 * single item tuple which is concatenated to the callbacks arguments.
722 * This allows callback input arg marshaling to always expect a
723 * tuple for user data. Note the
725 py_user_data = Py_BuildValue("(O)", py_user_data, NULL);
727 /* increment the ref borrowed from PyTuple_GetItem above */
728 Py_INCREF (py_user_data);
733 if (py_arg == Py_None) {
737 if (!PyCallable_Check (py_arg)) {
738 PyErr_Format (PyExc_TypeError,
739 "Callback needs to be a function or method not %s",
740 py_arg->ob_type->tp_name);
745 callable_info = (GICallableInfo *)callback_cache->interface_info;
747 closure = _pygi_make_native_closure (callable_info, callback_cache->scope, py_arg, py_user_data);
748 arg->v_pointer = closure->closure;
750 /* always decref the user data as _pygi_make_native_closure adds its own ref */
751 Py_XDECREF (py_user_data);
753 /* The PyGICClosure instance is used as user data passed into the C function.
754 * The return trip to python will marshal this back and pull the python user data out.
756 if (user_data_cache != NULL) {
757 state->args[user_data_cache->c_arg_index].arg_value.v_pointer = closure;
760 /* Setup a GDestroyNotify callback if this method supports it along with
761 * a user data field. The user data field is a requirement in order
762 * free resources and ref counts associated with this arguments closure.
763 * In case a user data field is not available, show a warning giving
764 * explicit information and setup a dummy notification to avoid a crash
765 * later on in _pygi_destroy_notify_callback_closure.
767 if (callback_cache->destroy_notify_index > 0) {
768 destroy_cache = _pygi_callable_cache_get_arg (callable_cache, callback_cache->destroy_notify_index);
772 if (user_data_cache != NULL) {
773 state->args[destroy_cache->c_arg_index].arg_value.v_pointer = _pygi_invoke_closure_free;
775 char *full_name = pygi_callable_cache_get_full_name (callable_cache);
776 gchar *msg = g_strdup_printf("Callables passed to %s will leak references because "
777 "the method does not support a user_data argument. "
778 "See: https://bugzilla.gnome.org/show_bug.cgi?id=685598",
781 if (PyErr_WarnEx(PyExc_RuntimeWarning, msg, 2)) {
783 _pygi_invoke_closure_free(closure);
787 state->args[destroy_cache->c_arg_index].arg_value.v_pointer = _pygi_destroy_notify_dummy;
791 /* Use the PyGIClosure as data passed to cleanup for GI_SCOPE_TYPE_CALL. */
792 *cleanup_data = closure;
798 _pygi_marshal_to_py_interface_callback (PyGIInvokeState *state,
799 PyGICallableCache *callable_cache,
800 PyGIArgCache *arg_cache,
803 PyGICallbackCache *callback_cache = (PyGICallbackCache *) arg_cache;
804 gssize user_data_index;
805 gssize destroy_notify_index;
806 gpointer user_data = NULL;
807 GDestroyNotify destroy_notify = NULL;
809 user_data_index = callback_cache->user_data_index;
810 destroy_notify_index = callback_cache->destroy_notify_index;
812 if (user_data_index != -1)
813 user_data = state->args[user_data_index].arg_value.v_pointer;
815 if (destroy_notify_index != -1)
816 destroy_notify = state->args[destroy_notify_index].arg_value.v_pointer;
818 return _pygi_ccallback_new (arg->v_pointer,
820 callback_cache->scope,
821 (GIFunctionInfo *) callback_cache->interface_info,
826 _callback_cache_free_func (PyGICallbackCache *cache)
829 if (cache->interface_info != NULL)
830 g_base_info_unref ( (GIBaseInfo *)cache->interface_info);
832 g_slice_free (PyGICallbackCache, cache);
837 _pygi_marshal_cleanup_from_py_interface_callback (PyGIInvokeState *state,
838 PyGIArgCache *arg_cache,
841 gboolean was_processed)
843 PyGICallbackCache *callback_cache = (PyGICallbackCache *)arg_cache;
845 if (was_processed && callback_cache->scope == GI_SCOPE_TYPE_CALL) {
846 _pygi_invoke_closure_free (data);
851 pygi_arg_callback_setup_from_info (PyGICallbackCache *arg_cache,
852 GITypeInfo *type_info,
853 GIArgInfo *arg_info, /* may be null */
855 PyGIDirection direction,
856 GIInterfaceInfo *iface_info,
857 PyGICallableCache *callable_cache)
859 PyGIArgCache *cache = (PyGIArgCache *)arg_cache;
860 gssize child_offset = 0;
862 if (!pygi_arg_base_setup ((PyGIArgCache *)arg_cache,
870 if (callable_cache != NULL)
871 child_offset = callable_cache->args_offset;
873 ( (PyGIArgCache *)arg_cache)->destroy_notify = (GDestroyNotify)_callback_cache_free_func;
875 arg_cache->user_data_index = g_arg_info_get_closure (arg_info);
876 if (arg_cache->user_data_index != -1)
877 arg_cache->user_data_index += child_offset;
879 arg_cache->destroy_notify_index = g_arg_info_get_destroy (arg_info);
880 if (arg_cache->destroy_notify_index != -1)
881 arg_cache->destroy_notify_index += child_offset;
883 if (arg_cache->user_data_index >= 0) {
884 PyGIArgCache *user_data_arg_cache = pygi_arg_cache_alloc ();
885 user_data_arg_cache->meta_type = PYGI_META_ARG_TYPE_CHILD_WITH_PYARG;
886 user_data_arg_cache->direction = direction;
887 user_data_arg_cache->has_default = TRUE; /* always allow user data with a NULL default. */
888 _pygi_callable_cache_set_arg (callable_cache, arg_cache->user_data_index,
889 user_data_arg_cache);
892 if (arg_cache->destroy_notify_index >= 0) {
893 PyGIArgCache *destroy_arg_cache = pygi_arg_cache_alloc ();
894 destroy_arg_cache->meta_type = PYGI_META_ARG_TYPE_CHILD;
895 destroy_arg_cache->direction = direction;
896 _pygi_callable_cache_set_arg (callable_cache, arg_cache->destroy_notify_index,
900 arg_cache->scope = g_arg_info_get_scope (arg_info);
901 g_base_info_ref( (GIBaseInfo *)iface_info);
902 arg_cache->interface_info = iface_info;
904 if (direction & PYGI_DIRECTION_FROM_PYTHON) {
905 cache->from_py_marshaller = _pygi_marshal_from_py_interface_callback;
906 cache->from_py_cleanup = _pygi_marshal_cleanup_from_py_interface_callback;
909 if (direction & PYGI_DIRECTION_TO_PYTHON) {
910 cache->to_py_marshaller = _pygi_marshal_to_py_interface_callback;
917 pygi_arg_callback_new_from_info (GITypeInfo *type_info,
918 GIArgInfo *arg_info, /* may be null */
920 PyGIDirection direction,
921 GIInterfaceInfo *iface_info,
922 PyGICallableCache *callable_cache)
924 gboolean res = FALSE;
925 PyGICallbackCache *callback_cache;
927 callback_cache = g_slice_new0 (PyGICallbackCache);
928 if (callback_cache == NULL)
931 res = pygi_arg_callback_setup_from_info (callback_cache,
939 return (PyGIArgCache *)callback_cache;
941 pygi_arg_cache_free ((PyGIArgCache *)callback_cache);