On 8/13/19 5:37 PM, Richard W.M. Jones wrote:
Simple macro encapsulating the process for freeing a callback. --- generator/states-reply-simple.c | 4 +-- generator/states-reply-structured.c | 42 +++++++++-------------------- generator/states-reply.c | 4 +-- generator/states.c | 4 +-- lib/aio.c | 17 ++++-------- lib/debug.c | 6 +---- lib/internal.h | 14 ++++++++++ 7 files changed, 35 insertions(+), 56 deletions(-)
Handy if we keep lots of .free() sites, but less useful if we only .free during retirement (see my commentary in 2).
+++ b/lib/internal.h @@ -273,6 +273,20 @@ struct command { uint32_t error; /* Local errno value */ };
+/* Free a callback. + * + * Note this works for any type of callback because the basic layout + * of the struct is the same for all of them. Therefore casting cb to + * nbd_completion_callback does not change the effective code. + */ +#define FREE_CALLBACK(cb) \ + do { \ + nbd_completion_callback *_cb = (nbd_completion_callback *)&(cb); \ + if (_cb->callback != NULL && _cb->free != NULL) \ + _cb->free (_cb->user_data); \ + _cb->callback = NULL; \ + } while (0) +
Some nasty type-punning (probably violates strict C) but I don't see any problem with it working in practice, if we still want to keep it. -- Eric Blake, Principal Software Engineer Red Hat, Inc. +1-919-301-3226 Virtualization: qemu.org | libvirt.org