[Libguestfs] [PATCH libnbd 1/3] generator: Change Closure so it describes single callbacks.
Richard W.M. Jones
rjones at redhat.com
Wed Jul 24 16:17:51 UTC 2019
On Wed, Jul 24, 2019 at 10:02:04AM -0500, Eric Blake wrote:
> On 7/24/19 7:17 AM, Richard W.M. Jones wrote:
> > In preparation for closure lifetimes, split up the Closure so it no
> > longer describes a list of closures, but a single callback.
> >
> > This changes the API because functions which take 2 or more closures
> > now pass a separate user_data for each one.
> > ---
> > docs/libnbd.pod | 3 +-
> > examples/strict-structured-reads.c | 2 +-
> > generator/generator | 760 ++++++++++++----------------
> > generator/states-reply-simple.c | 2 +-
> > generator/states-reply-structured.c | 8 +-
> > lib/internal.h | 3 +-
> > lib/rw.c | 32 +-
> > 7 files changed, 364 insertions(+), 446 deletions(-)
> >
> > diff --git a/docs/libnbd.pod b/docs/libnbd.pod
> > index 5608e63..631bb3b 100644
> > --- a/docs/libnbd.pod
> > +++ b/docs/libnbd.pod
> > @@ -487,8 +487,7 @@ C<nbd_set_debug_callback>, C<nbd_pread_callback>). Libnbd can call
> > these functions while processing.
> >
> > Callbacks have an opaque C<void *user_data> pointer. This is passed
>
> Should we tweak this to explicitly call out "Callbacks in the C
> language", to differentiate it from bindings to other languages that do
> not do this?
Yes, the documentation is rather C-specific. I'll add it (but as
another patch on top).
> > -as the first parameter to the callback. libnbd functions that take
> > -two callback pointers share the same opaque data for both calls.
> > +as the first parameter to the callback.
> >
>
> > +++ b/generator/generator
> > @@ -849,10 +849,10 @@ and arg =
> > written by the function *)
> > | BytesPersistIn of string * string (* same as above, but buffer persists *)
> > | BytesPersistOut of string * string
> > -| Closure of bool * closure list (* void *opaque + one or more closures
> > - flag if true means callbacks persist
> > - in the handle, false means they only
> > - exist during the function call *)
> > +| Closure of bool * closure (* function pointer + void *opaque
> > + flag if true means callbacks persist
> > + in the handle, false means they only
> > + exist during the function call *)
>
> Do we still need the closure record type, or can/should we simplify
> further to:
>
> | Closure of bool * string * arg list
>
> (and later in the series, even further by dropping 'bool *')
There's actually no difference at the machine code level - both tuple
and struct have the same representation (same as it would be in C in
fact). So it comes down to which is nicer, and I think it's slightly
nicer to have the named fields.
> > | Flags of string (* NBD_CMD_FLAG_* flags *)
> > | Int of string (* small int *)
> > | Int64 of string (* 64 bit signed int *)
> > @@ -921,8 +921,8 @@ Return the state of the debug flag on this handle.";
> > "set_debug_callback", {
> > default_call with
> > args = [ Closure (true,
> > - [{ cbname="debug_fn";
> > - cbargs=[String "context"; String "msg"] }]) ];
> > + { cbname="debug_fn";
> > + cbargs=[String "context"; String "msg"] }) ];
>
> Keeping the record type means that you still have to provide names, vs.
> directly using tuples where we'd write:
>
> args = [ Closure (true, "debug_fn",
> [String "context"; String "msg"]) ];
Indeed.
> > @@ -3811,154 +3795,140 @@ let print_python_binding name { args; ret } =
> > *)
> > List.iter (
> > function
> > - | Closure (persistent, cls) ->
> > - pr "struct %s_user_data {\n" name;
> > - List.iter (
> > - fun { cbname } ->
> > - pr " PyObject *%s;\n" cbname
> > - ) cls;
> > - pr "};\n";
> > - pr "\n";
> > -
> > + | Closure (persistent, { cbname; cbargs }) ->
> > (* Persistent closures need an explicit function to decrement
> > * the closure refcounts and free the user_data struct.
>
> Comment needs a touchup now that there is no user_data struct.
This comment goes away in the following commit :-)
> > + pr " py_args = Py_BuildValue (\"(\"";
> > + List.iter (
> > + function
> > + | ArrayAndLen (UInt32 n, len) -> pr " \"O\""
> > + | BytesIn (n, len) -> pr " \"y#\""
> > + | Int n -> pr " \"i\""
> > + | Int64 n -> pr " \"L\""
> > + | Mutable (Int n) -> pr " \"O\""
> > + | String n -> pr " \"s\""
> > + | UInt64 n -> pr " \"K\""
> > + (* The following not yet implemented for callbacks XXX *)
> > + | ArrayAndLen _ | Bool _ | BytesOut _
> > + | BytesPersistIn _ | BytesPersistOut _
>
> Not your usual indentation style.
I think at some point I gave up fighting tuareg mode :-(
I need to ask Martin for the right settings to make it indent in the
preferred way.
Rich.
--
Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones
Read my programming and virtualization blog: http://rwmj.wordpress.com
virt-top is 'top' for virtual machines. Tiny program with many
powerful monitoring features, net stats, disk stats, logging, etc.
http://people.redhat.com/~rjones/virt-top
More information about the Libguestfs
mailing list