[Libguestfs] [PATCH 2/5] generator: daemon: Use a cleanup function to free XDR args struct.

Richard W.M. Jones rjones at redhat.com
Thu Apr 20 12:56:30 UTC 2017


Previously stubs were generated like this:

  void
  fn_stub (XDR *xdr_in)
  {
    struct guestfs_fn_args args;
    ...
    // on error paths, ‘goto done’
    ...
  done:
    xdr_free ((xdrproc_t) xdr_guestfs_fn_args, (char *) &args);
  }

This replaces the call to xdr_free with a generated cleanup function.
---
 generator/daemon.ml | 44 ++++++++++++++++++++++++++++++--------------
 1 file changed, 30 insertions(+), 14 deletions(-)

diff --git a/generator/daemon.ml b/generator/daemon.ml
index 83c0ad24c..535f99458 100644
--- a/generator/daemon.ml
+++ b/generator/daemon.ml
@@ -225,6 +225,33 @@ let generate_daemon_stubs actions () =
   List.iter (
     fun { name = name; style = ret, args, optargs; optional = optional } ->
       (* Generate server-side stubs. *)
+      let uc_name = String.uppercase_ascii name in
+
+      let args_passed_to_daemon = args @ args_of_optargs optargs in
+      let args_passed_to_daemon =
+        List.filter (function FileIn _ | FileOut _ -> false | _ -> true)
+          args_passed_to_daemon in
+
+      if args_passed_to_daemon <> [] then (
+        pr "#ifdef HAVE_ATTRIBUTE_CLEANUP\n";
+        pr "\n";
+        pr "#define CLEANUP_XDR_FREE_%s_ARGS \\\n" uc_name;
+        pr "    __attribute__((cleanup(cleanup_xdr_free_%s_args)))\n" name;
+        pr "\n";
+        pr "static void\n";
+        pr "cleanup_xdr_free_%s_args (struct guestfs_%s_args *argsp)\n"
+           name name;
+        pr "{\n";
+        pr "  xdr_free ((xdrproc_t) xdr_guestfs_%s_args, (char *) argsp);\n"
+           name;
+        pr "}\n";
+        pr "\n";
+        pr "#else /* !HAVE_ATTRIBUTE_CLEANUP */\n";
+        pr "#define CLEANUP_XDR_FREE_%s_ARGS\n" uc_name;
+        pr "#endif /* !HAVE_ATTRIBUTE_CLEANUP */\n";
+        pr "\n"
+      );
+
       pr "void\n";
       pr "%s_stub (XDR *xdr_in)\n" name;
       pr "{\n";
@@ -243,12 +270,10 @@ let generate_daemon_stubs actions () =
            pr "  char *r;\n"
       );
 
-      let args_passed_to_daemon = args @ args_of_optargs optargs in
-      let args_passed_to_daemon =
-        List.filter (function FileIn _ | FileOut _ -> false | _ -> true)
-          args_passed_to_daemon in
       if args_passed_to_daemon <> [] then (
-        pr "  struct guestfs_%s_args args;\n" name;
+        pr "  CLEANUP_XDR_FREE_%s_ARGS struct guestfs_%s_args args;\n"
+           uc_name name;
+        pr "  memset (&args, 0, sizeof args);\n";
         List.iter (
           function
           | Device n | Dev_or_Path n ->
@@ -316,8 +341,6 @@ let generate_daemon_stubs actions () =
 
       (* Decode arguments. *)
       if args_passed_to_daemon <> [] then (
-        pr "  memset (&args, 0, sizeof args);\n";
-        pr "\n";
         pr "  if (!xdr_guestfs_%s_args (xdr_in, &args)) {\n" name;
         if is_filein then
           pr "    cancel_receive ();\n";
@@ -498,14 +521,7 @@ let generate_daemon_stubs actions () =
             pr "  free (r);\n"
       );
 
-      (* Free the args. *)
       pr "done: ;\n";
-      (match args_passed_to_daemon with
-       | [] -> ()
-       | _ ->
-           pr "  xdr_free ((xdrproc_t) xdr_guestfs_%s_args, (char *) &args);\n"
-             name
-      );
       pr "}\n\n";
   ) (actions |> daemon_functions |> sort)
 
-- 
2.12.0




More information about the Libguestfs mailing list