diff options
author | Benjamin Berg <bberg@redhat.com> | 2020-11-13 00:24:54 +0100 |
---|---|---|
committer | Benjamin Berg <benjamin@sipsolutions.net> | 2022-12-26 15:37:36 +0100 |
commit | a837c9d7a2b8abb61f6a2ad404c306b30f32b848 (patch) | |
tree | f403c568659c954a32c27b9948463ded7eee4868 | |
parent | 5e6bc1023e6c8553534b04a34495e9470b06c11f (diff) | |
download | pygobject-a837c9d7a2b8abb61f6a2ad404c306b30f32b848.tar.gz |
closure: Marshal async callback handler if a default value is passed
Default values will usually not be marshaled, as such, this can be used
to flag that the async routine needs marshalling.
This is a bit backward in a way, but avoids having to expose the closure
information to the rest of the code.
-rw-r--r-- | gi/pygi-closure.c | 18 | ||||
-rw-r--r-- | gi/pygi-invoke-state-struct.h | 5 | ||||
-rw-r--r-- | gi/pygi-invoke.c | 2 |
3 files changed, 25 insertions, 0 deletions
diff --git a/gi/pygi-closure.c b/gi/pygi-closure.c index 6b3889c7..274d2489 100644 --- a/gi/pygi-closure.c +++ b/gi/pygi-closure.c @@ -23,6 +23,7 @@ #include "pygi-invoke.h" #include "pygi-ccallback.h" #include "pygi-info.h" +#include "pygi-async.h" extern PyObject *_PyGIDefaultArgPlaceholder; @@ -708,6 +709,23 @@ _pygi_marshal_from_py_interface_callback (PyGIInvokeState *state, callback_cache = (PyGICallbackCache *)arg_cache; + if (py_arg == _PyGIDefaultArgPlaceholder) { + /* We need to have an async to "marshal" instead in this case. */ + if (!state->py_async) + return FALSE; + + if (callback_cache->user_data_index <= 0) + return FALSE; + + user_data_cache = _pygi_callable_cache_get_arg (callable_cache, (guint)callback_cache->user_data_index); + + Py_INCREF (state->py_async); + arg->v_pointer = pygi_async_finish_cb; + state->args[user_data_cache->c_arg_index].arg_value.v_pointer = state->py_async; + + return TRUE; + } + if (callback_cache->user_data_index > 0) { user_data_cache = _pygi_callable_cache_get_arg (callable_cache, (guint)callback_cache->user_data_index); if (user_data_cache->py_arg_index < state->n_py_in_args) { diff --git a/gi/pygi-invoke-state-struct.h b/gi/pygi-invoke-state-struct.h index dbf4e665..22969bb1 100644 --- a/gi/pygi-invoke-state-struct.h +++ b/gi/pygi-invoke-state-struct.h @@ -56,6 +56,11 @@ typedef struct _PyGIInvokeState gboolean failed; + /* An awaitable to return for an async function that was called with + * default arguments. + */ + PyObject *py_async; + gpointer user_data; /* Function pointer to call with ffi. */ diff --git a/gi/pygi-invoke.c b/gi/pygi-invoke.c index 7b822e4b..4239f255 100644 --- a/gi/pygi-invoke.c +++ b/gi/pygi-invoke.c @@ -24,6 +24,7 @@ #include "pygi-marshal-cleanup.h" #include "pygi-error.h" #include "pygi-resulttuple.h" +#include "pygi-async.h" #include "pygi-foreign.h" #include "pygi-boxed.h" @@ -317,6 +318,7 @@ _invoke_state_clear (PyGIInvokeState *state, PyGIFunctionCache *function_cache) { _pygi_invoke_arg_state_free (state); Py_XDECREF (state->py_in_args); + Py_XDECREF (state->py_async); } static gboolean |