On 7/24/19 11:54 AM, Richard W.M. Jones wrote:
Previously closures had a crude flag which tells if they are
persistent or transient. Transient closures (flag = false) last for
the lifetime of the currently called libnbd function. Persistent
closures had an indefinite lifetime which could last for as long as
the handle. In language bindings handling persistent closures was
wasteful as we needed to register a "close callback" to free the
closure when the handle is closed. But if you had submitted thousands
of asynchronous commands you would end up registering thousands of
close callbacks.
We actually have far more information about the lifetime of closures.
We know precisely when they will no longer be needed by the library.
Callers can use this information to free up associated user data
earlier. In particular in language bindings we can remove roots /
decrement reference counts at the right place to free the closure,
without waiting for the handle to be closed.
The solution to this is to introduce the concept of a closure
lifetime. The callback is called with an extra valid_flag parameter
which is a bitmap containing LIBNBD_CALLBACK_VALID and/or
LIBNBD_CALLBACK_FREE. LIBNBD_CALLBACK_VALID corresponds to a normal
call of the callback function by the library. After the library has
finished with the callback (declaring that this callback will never be
needed or called again), it is called once more with
valid_flag == LIBNBD_CALLBACK_FREE.
(Note it is also possible for the library to call the callback with
valid_flag == LIBNBD_CALLBACK_VALID|LIBNBD_CALLBACK_FREE, meaning it's the
last valid call.)
Our mails crossed, and I had questions about the implementation of v1
that aren't addressed here. But I'm also okay if you check this one in
as-is, and I can write a followup patch that shuffles things around per
my v1 comments as part of rebasing my auto-retire patches on top of this.
--
Eric Blake, Principal Software Engineer
Red Hat, Inc. +1-919-301-3226
Virtualization:
qemu.org |
libvirt.org