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-private.h"
21 #include "pygi-closure.h"
22 #include "pygi-error.h"
23 #include "pygi-marshal-cleanup.h"
26 typedef struct _PyGICallbackCache
28 PyGIArgCache arg_cache;
29 gssize user_data_index;
30 gssize destroy_notify_index;
32 GIInterfaceInfo *interface_info;
35 /* This maintains a list of closures which can be free'd whenever
36 as they have been called. We will free them on the next
37 library function call.
39 static GSList* async_free_list;
42 _pygi_closure_assign_pyobj_to_retval (gpointer retval,
44 PyGIArgCache *arg_cache)
49 switch (arg_cache->type_tag) {
50 case GI_TYPE_TAG_BOOLEAN:
51 *((ffi_sarg *) retval) = arg->v_boolean;
53 case GI_TYPE_TAG_INT8:
54 *((ffi_sarg *) retval) = arg->v_int8;
56 case GI_TYPE_TAG_UINT8:
57 *((ffi_arg *) retval) = arg->v_uint8;
59 case GI_TYPE_TAG_INT16:
60 *((ffi_sarg *) retval) = arg->v_int16;
62 case GI_TYPE_TAG_UINT16:
63 *((ffi_arg *) retval) = arg->v_uint16;
65 case GI_TYPE_TAG_INT32:
66 *((ffi_sarg *) retval) = arg->v_int32;
68 case GI_TYPE_TAG_UINT32:
69 *((ffi_arg *) retval) = arg->v_uint32;
71 case GI_TYPE_TAG_INT64:
72 *((ffi_sarg *) retval) = arg->v_int64;
74 case GI_TYPE_TAG_UINT64:
75 *((ffi_arg *) retval) = arg->v_uint64;
77 case GI_TYPE_TAG_FLOAT:
78 *((gfloat *) retval) = arg->v_float;
80 case GI_TYPE_TAG_DOUBLE:
81 *((gdouble *) retval) = arg->v_double;
83 case GI_TYPE_TAG_GTYPE:
84 *((ffi_arg *) retval) = arg->v_ulong;
86 case GI_TYPE_TAG_UNICHAR:
87 *((ffi_arg *) retval) = arg->v_uint32;
89 case GI_TYPE_TAG_INTERFACE:
91 GIBaseInfo *interface_info;
93 interface_info = ((PyGIInterfaceCache *) arg_cache)->interface_info;
95 switch (g_base_info_get_type (interface_info)) {
96 case GI_INFO_TYPE_ENUM:
97 *(ffi_sarg *) retval = arg->v_int;
99 case GI_INFO_TYPE_FLAGS:
100 *(ffi_arg *) retval = arg->v_uint;
103 *(ffi_arg *) retval = (ffi_arg) arg->v_pointer;
110 *(ffi_arg *) retval = (ffi_arg) arg->v_pointer;
116 _pygi_closure_assign_pyobj_to_out_argument (gpointer out_arg,
118 PyGIArgCache *arg_cache)
123 switch (arg_cache->type_tag) {
124 case GI_TYPE_TAG_BOOLEAN:
125 *((gboolean *) out_arg) = arg->v_boolean;
127 case GI_TYPE_TAG_INT8:
128 *((gint8 *) out_arg) = arg->v_int8;
130 case GI_TYPE_TAG_UINT8:
131 *((guint8 *) out_arg) = arg->v_uint8;
133 case GI_TYPE_TAG_INT16:
134 *((gint16 *) out_arg) = arg->v_int16;
136 case GI_TYPE_TAG_UINT16:
137 *((guint16 *) out_arg) = arg->v_uint16;
139 case GI_TYPE_TAG_INT32:
140 *((gint32 *) out_arg) = arg->v_int32;
142 case GI_TYPE_TAG_UINT32:
143 *((guint32 *) out_arg) = arg->v_uint32;
145 case GI_TYPE_TAG_INT64:
146 *((gint64 *) out_arg) = arg->v_int64;
148 case GI_TYPE_TAG_UINT64:
149 *((glong *) out_arg) = arg->v_uint64;
151 case GI_TYPE_TAG_FLOAT:
152 *((gfloat *) out_arg) = arg->v_float;
154 case GI_TYPE_TAG_DOUBLE:
155 *((gdouble *) out_arg) = arg->v_double;
157 case GI_TYPE_TAG_GTYPE:
158 *((gulong *) out_arg) = arg->v_ulong;
160 case GI_TYPE_TAG_UNICHAR:
161 *((guint32 *) out_arg) = arg->v_uint32;
163 case GI_TYPE_TAG_INTERFACE:
165 GIBaseInfo *interface_info;
167 interface_info = ((PyGIInterfaceCache *) arg_cache)->interface_info;
169 switch (g_base_info_get_type (interface_info)) {
170 case GI_INFO_TYPE_ENUM:
171 *(gint *) out_arg = arg->v_int;
173 case GI_INFO_TYPE_FLAGS:
174 *(guint *) out_arg = arg->v_uint;
176 case GI_INFO_TYPE_STRUCT:
177 if (!arg_cache->is_pointer) {
178 if (arg->v_pointer != NULL) {
179 gsize item_size = _pygi_g_type_info_size (arg_cache->type_info);
180 memcpy (out_arg, arg->v_pointer, item_size);
185 /* Fall through if pointer */
187 *((gpointer *) out_arg) = arg->v_pointer;
194 *((gpointer *) out_arg) = arg->v_pointer;
200 _pygi_closure_convert_ffi_arguments (PyGIInvokeArgState *state,
201 PyGICallableCache *cache,
206 for (i = 0; i < _pygi_callable_cache_args_len (cache); i++) {
207 PyGIArgCache *arg_cache = g_ptr_array_index (cache->args_cache, i);
209 if (arg_cache->direction & PYGI_DIRECTION_FROM_PYTHON) {
210 state[i].arg_value.v_pointer = * (gpointer *) args[i];
212 if (state[i].arg_value.v_pointer == NULL)
215 state[i].arg_pointer.v_pointer = state[i].arg_value.v_pointer;
216 state[i].arg_value = *(GIArgument *) state[i].arg_value.v_pointer;
220 switch (arg_cache->type_tag) {
221 case GI_TYPE_TAG_BOOLEAN:
222 state[i].arg_value.v_boolean = * (gboolean *) args[i];
224 case GI_TYPE_TAG_INT8:
225 state[i].arg_value.v_int8 = * (gint8 *) args[i];
227 case GI_TYPE_TAG_UINT8:
228 state[i].arg_value.v_uint8 = * (guint8 *) args[i];
230 case GI_TYPE_TAG_INT16:
231 state[i].arg_value.v_int16 = * (gint16 *) args[i];
233 case GI_TYPE_TAG_UINT16:
234 state[i].arg_value.v_uint16 = * (guint16 *) args[i];
236 case GI_TYPE_TAG_INT32:
237 state[i].arg_value.v_int32 = * (gint32 *) args[i];
239 case GI_TYPE_TAG_UINT32:
240 state[i].arg_value.v_uint32 = * (guint32 *) args[i];
242 case GI_TYPE_TAG_INT64:
243 state[i].arg_value.v_int64 = * (glong *) args[i];
245 case GI_TYPE_TAG_UINT64:
246 state[i].arg_value.v_uint64 = * (glong *) args[i];
248 case GI_TYPE_TAG_FLOAT:
249 state[i].arg_value.v_float = * (gfloat *) args[i];
251 case GI_TYPE_TAG_DOUBLE:
252 state[i].arg_value.v_double = * (gdouble *) args[i];
254 case GI_TYPE_TAG_UTF8:
255 state[i].arg_value.v_string = * (gchar **) args[i];
257 case GI_TYPE_TAG_INTERFACE:
259 GIBaseInfo *interface;
260 GIInfoType interface_type;
262 interface = ((PyGIInterfaceCache *) arg_cache)->interface_info;
263 interface_type = g_base_info_get_type (interface);
265 if (interface_type == GI_INFO_TYPE_ENUM) {
266 state[i].arg_value.v_int = * (gint *) args[i];
267 } else if (interface_type == GI_INFO_TYPE_FLAGS) {
268 state[i].arg_value.v_uint = * (guint *) args[i];
270 state[i].arg_value.v_pointer = * (gpointer *) args[i];
274 case GI_TYPE_TAG_ERROR:
275 case GI_TYPE_TAG_GHASH:
276 case GI_TYPE_TAG_GLIST:
277 case GI_TYPE_TAG_GSLIST:
278 case GI_TYPE_TAG_ARRAY:
279 case GI_TYPE_TAG_VOID:
280 state[i].arg_value.v_pointer = * (gpointer *) args[i];
283 g_warning ("Unhandled type tag %s",
284 g_type_tag_to_string (arg_cache->type_tag));
285 state[i].arg_value.v_pointer = 0;
290 gssize error_index = _pygi_callable_cache_args_len (cache);
292 state[error_index].arg_value.v_pointer = * (gpointer *) args[error_index];
297 _invoke_state_init_from_cache (PyGIInvokeState *state,
298 PyGIClosureCache *closure_cache,
301 PyGICallableCache *cache = (PyGICallableCache *) closure_cache;
303 state->n_args = _pygi_callable_cache_args_len (cache);
304 state->n_py_in_args = state->n_args;
306 /* Increment after setting the number of Python input args */
311 state->py_in_args = PyTuple_New (state->n_py_in_args);
312 if (state->py_in_args == NULL) {
320 if (!_pygi_invoke_arg_state_init (state)) {
324 state->ffi_args = NULL;
326 _pygi_closure_convert_ffi_arguments (state->args, cache, args);
331 _invoke_state_clear (PyGIInvokeState *state)
333 _pygi_invoke_arg_state_free (state);
334 Py_XDECREF (state->py_in_args);
338 _pygi_closure_convert_arguments (PyGIInvokeState *state,
339 PyGIClosureCache *closure_cache)
341 PyGICallableCache *cache = (PyGICallableCache *) closure_cache;
342 gssize n_in_args = 0;
345 for (i = 0; i < _pygi_callable_cache_args_len (cache); i++) {
346 PyGIArgCache *arg_cache;
348 arg_cache = g_ptr_array_index (cache->args_cache, i);
350 if (arg_cache->direction & PYGI_DIRECTION_TO_PYTHON) {
353 if (cache->user_data_index == i) {
354 if (state->user_data == NULL) {
355 /* user_data can be NULL for connect functions which don't accept
356 * user_data or as the default for user_data in the middle of function
362 /* Extend the callbacks args with user_data as variable args. */
363 gssize j, user_data_len;
364 PyObject *py_user_data = state->user_data;
366 if (!PyTuple_Check (py_user_data)) {
367 PyErr_SetString (PyExc_TypeError, "expected tuple for callback user_data");
371 user_data_len = PyTuple_Size (py_user_data);
372 _PyTuple_Resize (&state->py_in_args,
373 state->n_py_in_args + user_data_len - 1);
375 for (j = 0; j < user_data_len; j++, n_in_args++) {
376 value = PyTuple_GetItem (py_user_data, j);
378 PyTuple_SET_ITEM (state->py_in_args, n_in_args, value);
380 /* We can assume user_data args are never going to be inout,
381 * so just continue here.
385 } else if (arg_cache->meta_type != PYGI_META_ARG_TYPE_PARENT) {
388 value = arg_cache->to_py_marshaller (state,
391 &state->args[i].arg_value);
394 pygi_marshal_cleanup_args_to_py_parameter_fail (state,
401 PyTuple_SET_ITEM (state->py_in_args, n_in_args, value);
406 if (_PyTuple_Resize (&state->py_in_args, n_in_args) == -1)
413 _pygi_closure_set_out_arguments (PyGIInvokeState *state,
414 PyGICallableCache *cache,
419 gssize i_py_retval = 0;
422 if (cache->return_cache->type_tag != GI_TYPE_TAG_VOID) {
423 PyObject *item = py_retval;
425 if (PyTuple_Check (py_retval)) {
426 item = PyTuple_GET_ITEM (py_retval, 0);
429 success = cache->return_cache->from_py_marshaller (state,
434 &state->args[0].arg_cleanup_data);
437 pygi_marshal_cleanup_args_return_fail (state,
442 _pygi_closure_assign_pyobj_to_retval (resp, &state->return_arg,
443 cache->return_cache);
447 for (i = 0; i < _pygi_callable_cache_args_len (cache); i++) {
448 PyGIArgCache *arg_cache = g_ptr_array_index (cache->args_cache, i);
450 if (arg_cache->direction & PYGI_DIRECTION_FROM_PYTHON) {
451 PyObject *item = py_retval;
453 if (arg_cache->type_tag == GI_TYPE_TAG_ERROR) {
454 * (GError **) state->args[i].arg_pointer.v_pointer = NULL;
458 if (PyTuple_Check (py_retval)) {
459 item = PyTuple_GET_ITEM (py_retval, i_py_retval);
460 } else if (i_py_retval != 0) {
461 pygi_marshal_cleanup_args_to_py_parameter_fail (state,
467 success = arg_cache->from_py_marshaller (state,
471 &state->args[i].arg_value,
472 &state->args[i_py_retval].arg_cleanup_data);
475 pygi_marshal_cleanup_args_to_py_parameter_fail (state,
481 _pygi_closure_assign_pyobj_to_out_argument (state->args[i].arg_pointer.v_pointer,
482 &state->args[i].arg_value, arg_cache);
492 _pygi_closure_clear_retvals (PyGIInvokeState *state,
493 PyGICallableCache *cache,
497 GIArgument arg = { 0, };
499 if (cache->return_cache->type_tag != GI_TYPE_TAG_VOID) {
500 _pygi_closure_assign_pyobj_to_retval (resp, &arg,
501 cache->return_cache);
504 for (i = 0; i < _pygi_callable_cache_args_len (cache); i++) {
505 PyGIArgCache *arg_cache = g_ptr_array_index (cache->args_cache, i);
507 if (arg_cache->direction & PYGI_DIRECTION_FROM_PYTHON) {
508 _pygi_closure_assign_pyobj_to_out_argument (state->args[i].arg_pointer.v_pointer,
514 gssize error_index = state->n_args - 1;
515 GError **error = (GError **) state->args[error_index].arg_value.v_pointer;
518 pygi_gerror_exception_check (error);
524 _pygi_invoke_closure_clear_py_data(PyGICClosure *invoke_closure)
526 PyGILState_STATE state = PyGILState_Ensure();
528 Py_CLEAR (invoke_closure->function);
529 Py_CLEAR (invoke_closure->user_data);
531 PyGILState_Release (state);
535 _pygi_closure_handle (ffi_cif *cif,
540 PyGILState_STATE py_state;
541 PyGICClosure *closure = data;
544 PyGIInvokeState state = { 0, };
546 /* Ignore closures when Python is not initialized. This can happen in cases
547 * where calling Python implemented vfuncs can happen at shutdown time.
548 * See: https://bugzilla.gnome.org/show_bug.cgi?id=722562 */
549 if (!Py_IsInitialized()) {
553 /* Lock the GIL as we are coming into this code without the lock and we
554 may be executing python code */
555 py_state = PyGILState_Ensure ();
557 if (closure->cache == NULL) {
558 closure->cache = pygi_closure_cache_new ((GICallableInfo *) closure->info);
560 if (closure->cache == NULL)
564 state.user_data = closure->user_data;
566 _invoke_state_init_from_cache (&state, closure->cache, args);
568 if (!_pygi_closure_convert_arguments (&state, closure->cache)) {
569 _pygi_closure_clear_retvals (&state, closure->cache, result);
573 retval = PyObject_CallObject ( (PyObject *) closure->function, state.py_in_args);
575 if (retval == NULL) {
576 _pygi_closure_clear_retvals (&state, closure->cache, result);
580 pygi_marshal_cleanup_args_to_py_marshal_success (&state, closure->cache);
581 success = _pygi_closure_set_out_arguments (&state, closure->cache, retval, result);
584 pygi_marshal_cleanup_args_from_py_marshal_success (&state, closure->cache);
585 _pygi_closure_clear_retvals (&state, closure->cache, result);
592 if (PyErr_Occurred ())
595 /* Now that the closure has finished we can make a decision about how
596 to free it. Scope call gets free'd at the end of wrap_g_function_info_invoke.
597 Scope notified will be freed when the notify is called.
598 Scope async closures free only their python data now and the closure later
599 during the next creation of a closure. This minimizes potential ref leaks
600 at least in regards to the python objects.
601 (you can't free the closure you are currently using!)
603 switch (closure->scope) {
604 case GI_SCOPE_TYPE_CALL:
605 case GI_SCOPE_TYPE_NOTIFIED:
607 case GI_SCOPE_TYPE_ASYNC:
608 /* Append this PyGICClosure to a list of closure that we will free
609 after we're done with this function invokation */
610 _pygi_invoke_closure_clear_py_data(closure);
611 async_free_list = g_slist_prepend (async_free_list, closure);
614 g_error ("Invalid scope reached inside %s. Possibly a bad annotation?",
615 g_base_info_get_name (closure->info));
618 _invoke_state_clear (&state);
619 PyGILState_Release (py_state);
622 void _pygi_invoke_closure_free (gpointer data)
624 PyGICClosure* invoke_closure = (PyGICClosure *) data;
626 g_callable_info_free_closure (invoke_closure->info,
627 invoke_closure->closure);
629 if (invoke_closure->info)
630 g_base_info_unref ( (GIBaseInfo*) invoke_closure->info);
632 if (invoke_closure->cache != NULL)
633 pygi_callable_cache_free ((PyGICallableCache *) invoke_closure->cache);
635 _pygi_invoke_closure_clear_py_data(invoke_closure);
637 g_slice_free (PyGICClosure, invoke_closure);
642 _pygi_make_native_closure (GICallableInfo* info,
644 PyObject *py_function,
645 gpointer py_user_data)
647 PyGICClosure *closure;
648 ffi_closure *fficlosure;
650 /* Begin by cleaning up old async functions */
651 g_slist_free_full (async_free_list, (GDestroyNotify) _pygi_invoke_closure_free);
652 async_free_list = NULL;
654 /* Build the closure itself */
655 closure = g_slice_new0 (PyGICClosure);
656 closure->info = (GICallableInfo *) g_base_info_ref ( (GIBaseInfo *) info);
657 closure->function = py_function;
658 closure->user_data = py_user_data;
660 Py_INCREF (py_function);
661 Py_XINCREF (closure->user_data);
664 g_callable_info_prepare_closure (info, &closure->cif, _pygi_closure_handle,
666 closure->closure = fficlosure;
668 /* Give the closure the information it needs to determine when
669 to free itself later */
670 closure->scope = scope;
675 /* _pygi_destroy_notify_dummy:
677 * Dummy method used in the occasion when a method has a GDestroyNotify
678 * argument without user data.
681 _pygi_destroy_notify_dummy (gpointer data) {
685 _pygi_marshal_from_py_interface_callback (PyGIInvokeState *state,
686 PyGICallableCache *callable_cache,
687 PyGIArgCache *arg_cache,
690 gpointer *cleanup_data)
692 GICallableInfo *callable_info;
693 PyGICClosure *closure;
694 PyGIArgCache *user_data_cache = NULL;
695 PyGIArgCache *destroy_cache = NULL;
696 PyGICallbackCache *callback_cache;
697 PyObject *py_user_data = NULL;
699 callback_cache = (PyGICallbackCache *)arg_cache;
701 if (callback_cache->user_data_index > 0) {
702 user_data_cache = _pygi_callable_cache_get_arg (callable_cache, callback_cache->user_data_index);
703 if (user_data_cache->py_arg_index < state->n_py_in_args) {
704 /* py_user_data is a borrowed reference. */
705 py_user_data = PyTuple_GetItem (state->py_in_args, user_data_cache->py_arg_index);
708 /* NULL out user_data if it was not supplied and the default arg placeholder
711 if (py_user_data == _PyGIDefaultArgPlaceholder) {
713 } else if (callable_cache->user_data_varargs_index < 0) {
714 /* For non-variable length user data, place the user data in a
715 * single item tuple which is concatenated to the callbacks arguments.
716 * This allows callback input arg marshaling to always expect a
717 * tuple for user data. Note the
719 py_user_data = Py_BuildValue("(O)", py_user_data, NULL);
721 /* increment the ref borrowed from PyTuple_GetItem above */
722 Py_INCREF (py_user_data);
727 if (py_arg == Py_None) {
731 if (!PyCallable_Check (py_arg)) {
732 PyErr_Format (PyExc_TypeError,
733 "Callback needs to be a function or method not %s",
734 py_arg->ob_type->tp_name);
739 callable_info = (GICallableInfo *)callback_cache->interface_info;
741 closure = _pygi_make_native_closure (callable_info, callback_cache->scope, py_arg, py_user_data);
742 arg->v_pointer = closure->closure;
744 /* always decref the user data as _pygi_make_native_closure adds its own ref */
745 Py_XDECREF (py_user_data);
747 /* The PyGICClosure instance is used as user data passed into the C function.
748 * The return trip to python will marshal this back and pull the python user data out.
750 if (user_data_cache != NULL) {
751 state->args[user_data_cache->c_arg_index].arg_value.v_pointer = closure;
754 /* Setup a GDestroyNotify callback if this method supports it along with
755 * a user data field. The user data field is a requirement in order
756 * free resources and ref counts associated with this arguments closure.
757 * In case a user data field is not available, show a warning giving
758 * explicit information and setup a dummy notification to avoid a crash
759 * later on in _pygi_destroy_notify_callback_closure.
761 if (callback_cache->destroy_notify_index > 0) {
762 destroy_cache = _pygi_callable_cache_get_arg (callable_cache, callback_cache->destroy_notify_index);
766 if (user_data_cache != NULL) {
767 state->args[destroy_cache->c_arg_index].arg_value.v_pointer = _pygi_invoke_closure_free;
769 char *full_name = pygi_callable_cache_get_full_name (callable_cache);
770 gchar *msg = g_strdup_printf("Callables passed to %s will leak references because "
771 "the method does not support a user_data argument. "
772 "See: https://bugzilla.gnome.org/show_bug.cgi?id=685598",
775 if (PyErr_WarnEx(PyExc_RuntimeWarning, msg, 2)) {
777 _pygi_invoke_closure_free(closure);
781 state->args[destroy_cache->c_arg_index].arg_value.v_pointer = _pygi_destroy_notify_dummy;
785 /* Use the PyGIClosure as data passed to cleanup for GI_SCOPE_TYPE_CALL. */
786 *cleanup_data = closure;
792 _pygi_marshal_to_py_interface_callback (PyGIInvokeState *state,
793 PyGICallableCache *callable_cache,
794 PyGIArgCache *arg_cache,
797 PyGICallbackCache *callback_cache = (PyGICallbackCache *) arg_cache;
798 gssize user_data_index;
799 gssize destroy_notify_index;
800 gpointer user_data = NULL;
801 GDestroyNotify destroy_notify = NULL;
803 user_data_index = callback_cache->user_data_index;
804 destroy_notify_index = callback_cache->destroy_notify_index;
806 if (user_data_index != -1)
807 user_data = state->args[user_data_index].arg_value.v_pointer;
809 if (destroy_notify_index != -1)
810 destroy_notify = state->args[destroy_notify_index].arg_value.v_pointer;
812 return _pygi_ccallback_new (arg->v_pointer,
814 callback_cache->scope,
815 (GIFunctionInfo *) callback_cache->interface_info,
820 _callback_cache_free_func (PyGICallbackCache *cache)
823 if (cache->interface_info != NULL)
824 g_base_info_unref ( (GIBaseInfo *)cache->interface_info);
826 g_slice_free (PyGICallbackCache, cache);
831 _pygi_marshal_cleanup_from_py_interface_callback (PyGIInvokeState *state,
832 PyGIArgCache *arg_cache,
835 gboolean was_processed)
837 PyGICallbackCache *callback_cache = (PyGICallbackCache *)arg_cache;
839 if (was_processed && callback_cache->scope == GI_SCOPE_TYPE_CALL) {
840 _pygi_invoke_closure_free (data);
845 pygi_arg_callback_setup_from_info (PyGICallbackCache *arg_cache,
846 GITypeInfo *type_info,
847 GIArgInfo *arg_info, /* may be null */
849 PyGIDirection direction,
850 GIInterfaceInfo *iface_info,
851 PyGICallableCache *callable_cache)
853 PyGIArgCache *cache = (PyGIArgCache *)arg_cache;
854 gssize child_offset = 0;
856 if (!pygi_arg_base_setup ((PyGIArgCache *)arg_cache,
864 if (callable_cache != NULL)
865 child_offset = callable_cache->args_offset;
867 ( (PyGIArgCache *)arg_cache)->destroy_notify = (GDestroyNotify)_callback_cache_free_func;
869 arg_cache->user_data_index = g_arg_info_get_closure (arg_info);
870 if (arg_cache->user_data_index != -1)
871 arg_cache->user_data_index += child_offset;
873 arg_cache->destroy_notify_index = g_arg_info_get_destroy (arg_info);
874 if (arg_cache->destroy_notify_index != -1)
875 arg_cache->destroy_notify_index += child_offset;
877 if (arg_cache->user_data_index >= 0) {
878 PyGIArgCache *user_data_arg_cache = pygi_arg_cache_alloc ();
879 user_data_arg_cache->meta_type = PYGI_META_ARG_TYPE_CHILD_WITH_PYARG;
880 user_data_arg_cache->direction = direction;
881 user_data_arg_cache->has_default = TRUE; /* always allow user data with a NULL default. */
882 _pygi_callable_cache_set_arg (callable_cache, arg_cache->user_data_index,
883 user_data_arg_cache);
886 if (arg_cache->destroy_notify_index >= 0) {
887 PyGIArgCache *destroy_arg_cache = pygi_arg_cache_alloc ();
888 destroy_arg_cache->meta_type = PYGI_META_ARG_TYPE_CHILD;
889 destroy_arg_cache->direction = direction;
890 _pygi_callable_cache_set_arg (callable_cache, arg_cache->destroy_notify_index,
894 arg_cache->scope = g_arg_info_get_scope (arg_info);
895 g_base_info_ref( (GIBaseInfo *)iface_info);
896 arg_cache->interface_info = iface_info;
898 if (direction & PYGI_DIRECTION_FROM_PYTHON) {
899 cache->from_py_marshaller = _pygi_marshal_from_py_interface_callback;
900 cache->from_py_cleanup = _pygi_marshal_cleanup_from_py_interface_callback;
903 if (direction & PYGI_DIRECTION_TO_PYTHON) {
904 cache->to_py_marshaller = _pygi_marshal_to_py_interface_callback;
911 pygi_arg_callback_new_from_info (GITypeInfo *type_info,
912 GIArgInfo *arg_info, /* may be null */
914 PyGIDirection direction,
915 GIInterfaceInfo *iface_info,
916 PyGICallableCache *callable_cache)
918 gboolean res = FALSE;
919 PyGICallbackCache *callback_cache;
921 callback_cache = g_slice_new0 (PyGICallbackCache);
922 if (callback_cache == NULL)
925 res = pygi_arg_callback_setup_from_info (callback_cache,
933 return (PyGIArgCache *)callback_cache;
935 pygi_arg_cache_free ((PyGIArgCache *)callback_cache);