diff options
author | Richard W.M. Jones <rjones@redhat.com> | 2012-10-15 21:35:13 +0100 |
---|---|---|
committer | Richard W.M. Jones <rjones@redhat.com> | 2012-10-15 22:38:27 +0100 |
commit | 99bd15ad0e900ce16fe16d2a58b4d6f8ba38a0fe (patch) | |
tree | a9213dcd076b9e8c32a6f82be0e36ce960e8b5b7 | |
parent | 3d46f7dc038f87e00a27e9f294d4115436f1ff23 (diff) | |
download | libguestfs-99bd15ad0e900ce16fe16d2a58b4d6f8ba38a0fe.tar.gz libguestfs-99bd15ad0e900ce16fe16d2a58b4d6f8ba38a0fe.tar.xz libguestfs-99bd15ad0e900ce16fe16d2a58b4d6f8ba38a0fe.zip |
generator: Add 'blocking' flag to marking blocking (long-running) functions.
In languages like Python where we release a global lock around
long-running libguestfs functions, it is also useful to *not* release
this lock for small, non-blocking functions.
Therefore mark all functions with a 'blocking' boolean flag. It
defaults to true, and is true by definition for all daemon functions.
For non-daemon functions, I have classified them manually.
Only when the blocking flag is set do we generate the code to release
and reacquire the lock around libguestfs calls.
-rw-r--r-- | generator/actions.ml | 62 | ||||
-rw-r--r-- | generator/checks.ml | 9 | ||||
-rw-r--r-- | generator/ocaml.ml | 7 | ||||
-rw-r--r-- | generator/python.ml | 31 | ||||
-rw-r--r-- | generator/types.ml | 6 |
5 files changed, 100 insertions, 15 deletions
diff --git a/generator/actions.ml b/generator/actions.ml index dc712349..e7f4fe64 100644 --- a/generator/actions.ml +++ b/generator/actions.ml @@ -31,7 +31,7 @@ let defaults = { name = ""; style = RErr, [], []; proc_nr = None; deprecated_by = None; optional = None; progress = false; camel_name = ""; cancellable = false; config_only = false; - once_had_no_optargs = false; + once_had_no_optargs = false; blocking = true; c_name = ""; c_function = ""; c_optarg_prefix = ""; non_c_aliases = [] } @@ -77,6 +77,7 @@ let test_functions = [ name = "internal_test"; style = RErr, test_all_args, test_all_optargs; in_fish = false; in_docs = false; cancellable = true; + blocking = false; shortdesc = "internal test function - do not use"; longdesc = "\ This is an internal test function which is used to test whether @@ -92,6 +93,7 @@ You probably don't want to call this function." }; name = "internal_test_only_optargs"; style = RErr, [], [OInt "test"]; in_fish = false; in_docs = false; cancellable = true; + blocking = false; shortdesc = "internal test function - do not use"; longdesc = "\ This is an internal test function which is used to test whether @@ -107,6 +109,7 @@ You probably don't want to call this function." }; name = "internal_test_63_optargs"; style = RErr, [], [OInt "opt1"; OInt "opt2"; OInt "opt3"; OInt "opt4"; OInt "opt5"; OInt "opt6"; OInt "opt7"; OInt "opt8"; OInt "opt9"; OInt "opt10"; OInt "opt11"; OInt "opt12"; OInt "opt13"; OInt "opt14"; OInt "opt15"; OInt "opt16"; OInt "opt17"; OInt "opt18"; OInt "opt19"; OInt "opt20"; OInt "opt21"; OInt "opt22"; OInt "opt23"; OInt "opt24"; OInt "opt25"; OInt "opt26"; OInt "opt27"; OInt "opt28"; OInt "opt29"; OInt "opt30"; OInt "opt31"; OInt "opt32"; OInt "opt33"; OInt "opt34"; OInt "opt35"; OInt "opt36"; OInt "opt37"; OInt "opt38"; OInt "opt39"; OInt "opt40"; OInt "opt41"; OInt "opt42"; OInt "opt43"; OInt "opt44"; OInt "opt45"; OInt "opt46"; OInt "opt47"; OInt "opt48"; OInt "opt49"; OInt "opt50"; OInt "opt51"; OInt "opt52"; OInt "opt53"; OInt "opt54"; OInt "opt55"; OInt "opt56"; OInt "opt57"; OInt "opt58"; OInt "opt59"; OInt "opt60"; OInt "opt61"; OInt "opt62"; OInt "opt63"]; in_fish = false; in_docs = false; cancellable = true; + blocking = false; shortdesc = "internal test function - do not use"; longdesc = "\ This is an internal test function which is used to test whether @@ -126,6 +129,7 @@ You probably don't want to call this function." } name = name; style = ret, [String "val"], []; in_fish = false; in_docs = false; + blocking = false; shortdesc = "internal test function - do not use"; longdesc = "\ This is an internal test function which is used to test whether @@ -139,6 +143,7 @@ You probably don't want to call this function." }; name = name ^ "err"; style = ret, [], []; in_fish = false; in_docs = false; + blocking = false; shortdesc = "internal test function - do not use"; longdesc = "\ This is an internal test function which is used to test whether @@ -162,6 +167,7 @@ let non_daemon_functions = test_functions @ [ name = "internal_test_set_output"; style = RErr, [String "filename"], []; in_fish = false; in_docs = false; + blocking = false; shortdesc = "internal test function - do not use"; longdesc = "\ This is an internal test function which is used to test whether @@ -176,6 +182,7 @@ You probably don't want to call this function." }; name = "internal_test_close_output"; style = RErr, [], []; in_fish = false; in_docs = false; + blocking = false; shortdesc = "internal test function - do not use"; longdesc = "\ This is an internal test function which is used to test whether @@ -208,6 +215,7 @@ very cheap to create, so create a new one for each launch." }; name = "wait_ready"; style = RErr, [], []; in_fish = false; deprecated_by = Some "launch"; + blocking = false; shortdesc = "wait until the qemu subprocess launches (no op)"; longdesc = "\ This function is a no op. @@ -235,6 +243,7 @@ Do not call this. See: C<guestfs_shutdown> instead." }; name = "add_cdrom"; style = RErr, [String "filename"], []; deprecated_by = Some "add_drive"; config_only = true; + blocking = false; shortdesc = "add a CD-ROM disk image to examine"; longdesc = "\ This function adds a virtual CD-ROM disk image to the guest. @@ -246,6 +255,7 @@ read-only disk images. Use C<guestfs_add_drive_ro> instead." }; name = "add_drive_ro"; style = RErr, [String "filename"], []; fish_alias = ["add-ro"]; config_only = true; + blocking = false; shortdesc = "add a drive in snapshot mode (read-only)"; longdesc = "\ This function is the equivalent of calling C<guestfs_add_drive_opts> @@ -257,6 +267,7 @@ automatically." }; name = "config"; style = RErr, [String "qemuparam"; OptString "qemuvalue"], []; config_only = true; + blocking = false; shortdesc = "add qemu parameters"; longdesc = "\ This can be used to add arbitrary qemu command line parameters @@ -272,6 +283,7 @@ C<qemuvalue> can be NULL." }; name = "set_qemu"; style = RErr, [OptString "qemu"], []; fish_alias = ["qemu"]; config_only = true; + blocking = false; shortdesc = "set the qemu binary"; longdesc = "\ Set the qemu binary that we will use. @@ -295,6 +307,7 @@ the qemu binary at the same time as the handle is created." }; { defaults with name = "get_qemu"; style = RConstString "qemu", [], []; + blocking = false; tests = [ InitNone, Always, TestRun ( [["get_qemu"]]) @@ -310,6 +323,7 @@ return the default qemu binary name." }; name = "set_path"; style = RErr, [OptString "searchpath"], []; fish_alias = ["path"]; config_only = true; + blocking = false; shortdesc = "set the search path"; longdesc = "\ Set the path that libguestfs searches for kernel and initrd.img. @@ -322,6 +336,7 @@ Setting C<path> to C<NULL> restores the default path." }; { defaults with name = "get_path"; style = RConstString "path", [], []; + blocking = false; tests = [ InitNone, Always, TestRun ( [["get_path"]]) @@ -337,6 +352,7 @@ return the default path." }; name = "set_append"; style = RErr, [OptString "append"], []; fish_alias = ["append"]; config_only = true; + blocking = false; shortdesc = "add options to kernel command line"; longdesc = "\ This function is used to add additional options to the @@ -351,6 +367,7 @@ are passed (libguestfs always adds a few of its own)." }; { defaults with name = "get_append"; style = RConstOptString "append", [], []; + blocking = false; (* This cannot be tested with the current framework. The * function can return NULL in normal operations, which the * test framework interprets as an error. @@ -367,6 +384,7 @@ If C<NULL> then no options are added." }; name = "set_autosync"; style = RErr, [Bool "autosync"], []; fish_alias = ["autosync"]; + blocking = false; shortdesc = "set autosync mode"; longdesc = "\ If C<autosync> is true, this enables autosync. Libguestfs will make a @@ -380,6 +398,7 @@ disabled by default)." }; { defaults with name = "get_autosync"; style = RBool "autosync", [], []; + blocking = false; tests = [ InitNone, Always, TestOutputTrue ( [["get_autosync"]]) @@ -392,6 +411,7 @@ Get the autosync flag." }; name = "set_verbose"; style = RErr, [Bool "verbose"], []; fish_alias = ["verbose"]; + blocking = false; shortdesc = "set verbose mode"; longdesc = "\ If C<verbose> is true, this turns on verbose messages. @@ -406,6 +426,7 @@ C<guestfs_set_event_callback>)." }; { defaults with name = "get_verbose"; style = RBool "verbose", [], []; + blocking = false; shortdesc = "get verbose mode"; longdesc = "\ This returns the verbose messages flag." }; @@ -413,6 +434,7 @@ This returns the verbose messages flag." }; { defaults with name = "is_ready"; style = RBool "ready", [], []; + blocking = false; tests = [ InitNone, Always, TestOutputTrue ( [["is_ready"]]) @@ -427,6 +449,7 @@ For more information on states, see L<guestfs(3)>." }; { defaults with name = "is_config"; style = RBool "config", [], []; + blocking = false; tests = [ InitNone, Always, TestOutputFalse ( [["is_config"]]) @@ -441,6 +464,7 @@ For more information on states, see L<guestfs(3)>." }; { defaults with name = "is_launching"; style = RBool "launching", [], []; + blocking = false; tests = [ InitNone, Always, TestOutputFalse ( [["is_launching"]]) @@ -456,6 +480,7 @@ For more information on states, see L<guestfs(3)>." }; name = "is_busy"; style = RBool "busy", [], []; in_docs = false; + blocking = false; tests = [ InitNone, Always, TestOutputFalse ( [["is_busy"]]) @@ -469,6 +494,7 @@ For more information on states, see L<guestfs(3)>." }; { defaults with name = "get_state"; style = RInt "state", [], []; + blocking = false; shortdesc = "get the current state"; longdesc = "\ This returns the current state as an opaque integer. This is @@ -480,6 +506,7 @@ For more information on states, see L<guestfs(3)>." }; name = "set_memsize"; style = RErr, [Int "memsize"], []; fish_alias = ["memsize"]; config_only = true; + blocking = false; shortdesc = "set memory allocated to the qemu subprocess"; longdesc = "\ This sets the memory size in megabytes allocated to the @@ -496,6 +523,7 @@ see L<guestfs(3)>." }; { defaults with name = "get_memsize"; style = RInt "memsize", [], []; + blocking = false; tests = [ InitNone, Always, TestOutputIntOp ( [["get_memsize"]], ">=", 256) @@ -516,6 +544,7 @@ see L<guestfs(3)>." }; name = "get_pid"; style = RInt "pid", [], []; fish_alias = ["pid"]; + blocking = false; tests = []; shortdesc = "get PID of qemu subprocess"; longdesc = "\ @@ -527,6 +556,7 @@ This is an internal call used for debugging and testing." }; { defaults with name = "version"; style = RStruct ("version", "version"), [], []; + blocking = false; tests = [ InitNone, Always, TestOutputStruct ( [["version"]], [CompareWithInt ("major", 1)]) @@ -568,6 +598,7 @@ Use C<guestfs_available> instead." }; name = "set_selinux"; style = RErr, [Bool "selinux"], []; fish_alias = ["selinux"]; config_only = true; + blocking = false; shortdesc = "set SELinux enabled or disabled at appliance boot"; longdesc = "\ This sets the selinux flag that is passed to the appliance @@ -582,6 +613,7 @@ see L<guestfs(3)>." }; { defaults with name = "get_selinux"; style = RBool "selinux", [], []; + blocking = false; shortdesc = "get SELinux enabled flag"; longdesc = "\ This returns the current setting of the selinux flag which @@ -594,6 +626,7 @@ see L<guestfs(3)>." }; name = "set_trace"; style = RErr, [Bool "trace"], []; fish_alias = ["trace"]; + blocking = false; tests = [ InitNone, Always, TestOutputFalse ( [["set_trace"; "false"]; @@ -618,6 +651,7 @@ C<guestfs_set_event_callback>)." }; { defaults with name = "get_trace"; style = RBool "trace", [], []; + blocking = false; shortdesc = "get command trace enabled flag"; longdesc = "\ Return the command trace flag." }; @@ -626,6 +660,7 @@ Return the command trace flag." }; name = "set_direct"; style = RErr, [Bool "direct"], []; fish_alias = ["direct"]; config_only = true; + blocking = false; shortdesc = "enable or disable direct appliance mode"; longdesc = "\ If the direct appliance mode flag is enabled, then stdin and @@ -644,6 +679,7 @@ The default is disabled." }; { defaults with name = "get_direct"; style = RBool "direct", [], []; + blocking = false; shortdesc = "get direct appliance mode flag"; longdesc = "\ Return the direct appliance mode flag." }; @@ -652,6 +688,7 @@ Return the direct appliance mode flag." }; name = "set_recovery_proc"; style = RErr, [Bool "recoveryproc"], []; fish_alias = ["recovery-proc"]; config_only = true; + blocking = false; shortdesc = "enable or disable the recovery process"; longdesc = "\ If this is called with the parameter C<false> then @@ -671,6 +708,7 @@ qemu, which is not very helpful." }; { defaults with name = "get_recovery_proc"; style = RBool "recoveryproc", [], []; + blocking = false; shortdesc = "get recovery process enabled flag"; longdesc = "\ Return the recovery process enabled flag." }; @@ -679,6 +717,7 @@ Return the recovery process enabled flag." }; name = "add_drive_with_if"; style = RErr, [String "filename"; String "iface"], []; deprecated_by = Some "add_drive"; config_only = true; + blocking = false; shortdesc = "add a drive specifying the QEMU block emulation to use"; longdesc = "\ This is the same as C<guestfs_add_drive> but it allows you @@ -687,6 +726,7 @@ to specify the QEMU interface emulation to use at run time." }; { defaults with name = "add_drive_ro_with_if"; style = RErr, [String "filename"; String "iface"], []; + blocking = false; deprecated_by = Some "add_drive"; config_only = true; shortdesc = "add a drive read-only specifying the QEMU block emulation to use"; longdesc = "\ @@ -1135,6 +1175,7 @@ See also C<guestfs_inspect_get_mountpoints>." }; name = "set_network"; style = RErr, [Bool "network"], []; fish_alias = ["network"]; config_only = true; + blocking = false; shortdesc = "set enable network flag"; longdesc = "\ If C<network> is true, then the network is enabled in the @@ -1149,6 +1190,7 @@ it has no effect." }; { defaults with name = "get_network"; style = RBool "network", [], []; + blocking = false; shortdesc = "get enable network flag"; longdesc = "\ This returns the enable network flag." }; @@ -1191,6 +1233,7 @@ not all belong to a single logical operating system name = "add_drive"; style = RErr, [String "filename"], [OBool "readonly"; OString "format"; OString "iface"; OString "name"; OString "label"]; once_had_no_optargs = true; + blocking = false; fish_alias = ["add"]; shortdesc = "add an image to examine or modify"; longdesc = "\ @@ -1294,6 +1337,7 @@ Please read L<guestfs(3)/INSPECTION> for more details." }; name = "debug_drives"; style = RStringList "cmdline", [], []; in_docs = false; + blocking = false; shortdesc = "debug the drives (internal use only)"; longdesc = "\ This returns the internal list of drives. 'debug' commands are @@ -1655,6 +1699,7 @@ Please read L<guestfs(3)/INSPECTION> for more details." }; name = "set_attach_method"; style = RErr, [String "attachmethod"], []; fish_alias = ["attach-method"]; config_only = true; + blocking = false; shortdesc = "set the attach method"; longdesc = "\ Set the method that libguestfs uses to connect to the back end @@ -1713,6 +1758,7 @@ attach method, do: { defaults with name = "get_attach_method"; style = RString "attachmethod", [], []; + blocking = false; tests = [ InitNone, Always, TestRun ( [["get_attach_method"]]) @@ -1866,6 +1912,7 @@ advice before using trademarks in applications. name = "set_pgroup"; style = RErr, [Bool "pgroup"], []; fish_alias = ["pgroup"]; config_only = true; + blocking = false; shortdesc = "set process group flag"; longdesc = "\ If C<pgroup> is true, child processes are placed into @@ -1882,6 +1929,7 @@ long-running commands gracefully (see C<guestfs_user_cancel>)." }; { defaults with name = "get_pgroup"; style = RBool "pgroup", [], []; + blocking = false; shortdesc = "get process group flag"; longdesc = "\ This returns the process group flag." }; @@ -1890,6 +1938,7 @@ This returns the process group flag." }; name = "set_smp"; style = RErr, [Int "smp"], []; fish_alias = ["smp"]; config_only = true; + blocking = false; shortdesc = "set number of virtual CPUs in appliance"; longdesc = "\ Change the number of virtual CPUs assigned to the appliance. The @@ -1901,6 +1950,7 @@ This function must be called before C<guestfs_launch>." }; { defaults with name = "get_smp"; style = RInt "smp", [], []; + blocking = false; shortdesc = "get number of virtual CPUs in appliance"; longdesc = "\ This returns the number of virtual CPUs assigned to the appliance." }; @@ -1972,6 +2022,7 @@ See L<guestfs(3)/MOUNT LOCAL> for full documentation." }; { defaults with name = "max_disks"; style = RInt "disks", [], []; + blocking = false; shortdesc = "maximum number of disks that may be added"; longdesc = "\ Return the maximum number of disks that may be added to a @@ -2363,6 +2414,7 @@ circumstances. See L<guestfs(3)/CVE-2010-3851>." }; { defaults with name = "remove_drive"; style = RErr, [String "label"], []; + blocking = false; tests = []; shortdesc = "remove a disk image"; longdesc = "\ @@ -2382,6 +2434,7 @@ disk is in use and stop you from doing this." }; { defaults with name = "set_libvirt_supported_credentials"; style = RErr, [StringList "creds"], []; + blocking = false; tests = []; shortdesc = "set libvirt credentials supported by calling program"; longdesc = "\ @@ -2421,6 +2474,7 @@ See L<guestfs(3)/LIBVIRT AUTHENTICATION> for documentation and example code." }; { defaults with name = "get_libvirt_requested_credentials"; style = RStringList "creds", [], []; + blocking = false; tests = []; shortdesc = "get list of credentials requested by libvirt"; longdesc = "\ @@ -2436,6 +2490,7 @@ See L<guestfs(3)/LIBVIRT AUTHENTICATION> for documentation and example code." }; { defaults with name = "get_libvirt_requested_credential_prompt"; style = RString "prompt", [Int "index"], []; + blocking = false; tests = []; shortdesc = "prompt of i'th requested credential"; longdesc = "\ @@ -2448,6 +2503,7 @@ See L<guestfs(3)/LIBVIRT AUTHENTICATION> for documentation and example code." }; { defaults with name = "get_libvirt_requested_credential_challenge"; style = RString "challenge", [Int "index"], []; + blocking = false; tests = []; shortdesc = "challenge of i'th requested credential"; longdesc = "\ @@ -2460,6 +2516,7 @@ See L<guestfs(3)/LIBVIRT AUTHENTICATION> for documentation and example code." }; { defaults with name = "get_libvirt_requested_credential_defresult"; style = RString "defresult", [Int "index"], []; + blocking = false; tests = []; shortdesc = "default result of i'th requested credential"; longdesc = "\ @@ -2472,6 +2529,7 @@ See L<guestfs(3)/LIBVIRT AUTHENTICATION> for documentation and example code." }; { defaults with name = "set_libvirt_requested_credential"; style = RErr, [Int "index"; BufferIn "cred"], []; + blocking = false; tests = []; shortdesc = "pass requested credential back to libvirt"; longdesc = "\ @@ -2483,6 +2541,7 @@ See L<guestfs(3)/LIBVIRT AUTHENTICATION> for documentation and example code." }; { defaults with name = "parse_environment"; style = RErr, [], []; + blocking = false; tests = []; shortdesc = "parse the environment and set handle flags accordingly"; longdesc = "\ @@ -2501,6 +2560,7 @@ C<guestfs_parse_environment_list>." }; { defaults with name = "parse_environment_list"; style = RErr, [StringList "environment"], []; + blocking = false; tests = []; shortdesc = "parse the environment and set handle flags accordingly"; longdesc = "\ diff --git a/generator/checks.ml b/generator/checks.ml index 8ebfd987..2cccf260 100644 --- a/generator/checks.ml +++ b/generator/checks.ml @@ -234,6 +234,15 @@ let () = ) ) (all_functions @ fish_commands); + (* Checking blocking flag is set on all daemon functions. *) + List.iter ( + function + | { name = name; blocking = false } -> + failwithf "%s: blocking flag should be 'true' on this daemon function" + name + | { blocking = true } -> () + ) daemon_functions; + (* Non-fish functions must have correct camel_name. *) List.iter ( fun { name = name; camel_name = camel_name } -> diff --git a/generator/ocaml.ml b/generator/ocaml.ml index bf96c153..b90aeb82 100644 --- a/generator/ocaml.ml +++ b/generator/ocaml.ml @@ -436,6 +436,7 @@ copy_table (char * const * argv) (* The wrappers. *) List.iter ( fun { name = name; style = (ret, args, optargs as style); + blocking = blocking; c_function = c_function; c_optarg_prefix = c_optarg_prefix } -> pr "/* Automatically generated wrapper for function\n"; pr " * "; @@ -571,11 +572,13 @@ copy_table (char * const * argv) ); pr "\n"; - pr " caml_enter_blocking_section ();\n"; + if blocking then + pr " caml_enter_blocking_section ();\n"; pr " r = %s " c_function; generate_c_call_args ~handle:"g" style; pr ";\n"; - pr " caml_leave_blocking_section ();\n"; + if blocking then + pr " caml_leave_blocking_section ();\n"; (* Free strings if we copied them above. *) List.iter ( diff --git a/generator/python.ml b/generator/python.ml index aa1ce8e9..39750557 100644 --- a/generator/python.ml +++ b/generator/python.ml @@ -248,12 +248,15 @@ free_strings (char **argv) (* Python wrapper functions. *) List.iter ( fun { name = name; style = (ret, args, optargs as style); + blocking = blocking; c_function = c_function; c_optarg_prefix = c_optarg_prefix } -> pr "static PyObject *\n"; pr "py_guestfs_%s (PyObject *self, PyObject *args)\n" name; pr "{\n"; - pr " PyThreadState *py_save = NULL;\n"; + if blocking then + pr " PyThreadState *py_save = NULL;\n"; + pr " PyObject *py_g;\n"; pr " guestfs_h *g;\n"; pr " PyObject *py_r;\n"; @@ -403,23 +406,27 @@ free_strings (char **argv) pr "\n" ); - (* Release Python GIL while running. This code is from - * libvirt/python/typewrappers.h. Thanks to Dan Berrange for - * showing us how to do this properly. - *) - pr " if (PyEval_ThreadsInitialized ())\n"; - pr " py_save = PyEval_SaveThread ();\n"; - pr "\n"; + if blocking then ( + (* Release Python GIL while running. This code is from + * libvirt/python/typewrappers.h. Thanks to Dan Berrange for + * showing us how to do this properly. + *) + pr " if (PyEval_ThreadsInitialized ())\n"; + pr " py_save = PyEval_SaveThread ();\n"; + pr "\n" + ); pr " r = %s " c_function; generate_c_call_args ~handle:"g" style; pr ";\n"; - - pr "\n"; - pr " if (PyEval_ThreadsInitialized ())\n"; - pr " PyEval_RestoreThread (py_save);\n"; pr "\n"; + if blocking then ( + pr " if (PyEval_ThreadsInitialized ())\n"; + pr " PyEval_RestoreThread (py_save);\n"; + pr "\n" + ); + List.iter ( function | Pathname _ | Device _ | Dev_or_Path _ | String _ | Key _ diff --git a/generator/types.ml b/generator/types.ml index 6469005f..cff3c6dd 100644 --- a/generator/types.ml +++ b/generator/types.ml @@ -393,6 +393,12 @@ type action = { once_had_no_optargs : bool; (* mark functions that once had no optargs but now do, so we can generate the required back-compat machinery *) + blocking : bool; (* Function blocks (long-running). All + daemon functions are blocking by + definition. Some functions that just + set flags in the handle are marked + non-blocking so that we don't add + machinery in various bindings. *) (* "Internal" data attached by the generator at various stages. This * doesn't need to (and shouldn't) be set when defining actions. |