[Libguestfs] [PATCH libnbd 2/3] python: Hold a refcount to persistent AIO buffer until command completion.

Richard W.M. Jones rjones at redhat.com
Wed Aug 14 21:05:13 UTC 2019


---
 generator/generator | 31 ++++++++++++++++++++++++++++---
 1 file changed, 28 insertions(+), 3 deletions(-)

diff --git a/generator/generator b/generator/generator
index f6a4856..9bcb08d 100755
--- a/generator/generator
+++ b/generator/generator
@@ -3982,6 +3982,13 @@ let print_python_closure_wrapper { cbname; cbargs } =
   pr "  const struct user_data *data = user_data;\n";
   pr "  int ret = 0;\n";
   pr "\n";
+  pr "  /* The C callback is always registered, even if there's no Python\n";
+  pr "   * callback.  This is because we may need to unregister an\n";
+  pr "   * associated persistent buffer.\n";
+  pr "   */\n";
+  pr "  if (data->fn == NULL)\n";
+  pr "    return 0;\n";
+  pr "\n";
   pr "  PyGILState_STATE py_save = PyGILState_UNLOCKED;\n";
   pr "  PyObject *py_args, *py_ret;\n";
   List.iter (
@@ -4253,10 +4260,24 @@ let print_python_binding name { args; optargs; ret; may_set_error } =
        pr "    }\n";
        pr "  }\n";
        pr "  else\n";
-       pr "    %s.callback = NULL; /* we're not going to call it */\n" cbname
+       pr "    %s_user_data->fn = NULL;\n" cbname
     | OFlags (n, _) -> pr "  %s_u32 = %s;\n" n n
   ) optargs;
 
+  (* If there is a BytesPersistIn/Out parameter then we need to
+   * increment the refcount and save the pointer into
+   * completion_callback.user_data so we can decrement the
+   * refcount on command completion.
+   *)
+  List.iter (
+    function
+    | BytesPersistIn (n, _) | BytesPersistOut (n, _) ->
+       pr "  /* Increment refcount since buffer may be saved by libnbd. */\n";
+       pr "  Py_INCREF (%s);\n" n;
+       pr "  completion_user_data->buf = %s;\n" n;
+    | _ -> ()
+  ) args;
+
   (* Call the underlying C function. *)
   pr "  ret = nbd_%s (h" name;
   List.iter (
@@ -4384,7 +4405,8 @@ let generate_python_methods_c () =
   pr " * and freed in the free_user_data function below.\n";
   pr " */\n";
   pr "struct user_data {\n";
-  pr "  PyObject *fn;    /* Pointer to Python function. */\n";
+  pr "  PyObject *fn;    /* Optional pointer to Python function. */\n";
+  pr "  PyObject *buf;   /* Optional pointer to persistent buffer. */\n";
   pr "};\n";
   pr "\n";
   pr "static struct user_data *\n";
@@ -4403,7 +4425,10 @@ let generate_python_methods_c () =
   pr "{\n";
   pr "  struct user_data *data = user_data;\n";
   pr "\n";
-  pr "  Py_DECREF (data->fn);\n";
+  pr "  if (data->fn != NULL)\n";
+  pr "    Py_DECREF (data->fn);\n";
+  pr "  if (data->buf != NULL)\n";
+  pr "    Py_DECREF (data->buf);\n";
   pr "  free (data);\n";
   pr "}\n";
   pr "\n";
-- 
2.22.0




More information about the Libguestfs mailing list