On 7/30/19 5:51 AM, Richard W.M. Jones wrote:
There was a theoretic race in this example: If the server was very fast at handling commands then it's possible that in a call such as:
cookie = nbd_aio_pread_callback (..., callback, ...); buffers[i].cookie = cookie;
nbd_aio_pread_callback finished and calls the callback before returning. buffers[i].cookie would therefore not be set, but the callback() function was checking the list of buffers for the cookie. This would have caused an abort() in the existing code, although we have never observed that.
The new code, instead of relying on the cookie, passes a pointer to &buffers[i], so the callback no longer needs to search the list of buffers (this is also quicker).
This necessitated another change however: previously we were copying buffers around to ensure that the next free buffer was always at &buffers[nr_buffers]. Instead of that introduce a new state (BUFFER_UNUSED) and search the short list of buffers once when looking for a free buffer.
Thanks: Eric Blake. --- examples/glib-main-loop.c | 96 +++++++++++++-------------------------- 1 file changed, 32 insertions(+), 64 deletions(-)
Avoids a potential race, and uses fewer lines of code. What's not to like about it :) ACK. -- Eric Blake, Principal Software Engineer Red Hat, Inc. +1-919-301-3226 Virtualization: qemu.org | libvirt.org