[pygobject/benzea/gio-asyncio: 3/7] closure: Marshal async callback handler if a default value is passed




commit a5877e6d0d421cd58ac1633ef58de37a3129b8c5
Author: Benjamin Berg <bberg redhat com>
Date:   Fri Nov 13 00:24:54 2020 +0100

    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.

 gi/pygi-closure.c             | 18 ++++++++++++++++++
 gi/pygi-invoke-state-struct.h |  5 +++++
 gi/pygi-invoke.c              |  2 ++
 3 files changed, 25 insertions(+)
---
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


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]