On 6/25/19 4:06 AM, Richard W.M. Jones wrote: > On Wed, Jun 19, 2019 at 09:11:52PM -0500, Eric Blake wrote: >> When we are blocked waiting for POLLOUT during a request, and happen >> to receive notice of POLLIN instead, we know that the work done in >> response to POLLIN will be non-blocking (it returns to %.READY as soon >> as it would block, which in turn jumps right back into ISSUE_COMMAND >> because we have a pending request not fully sent yet). Since the >> jaunt through REPLY was non-blocking, it is unlikely that the POLLOUT >> situation has changed in the meantime, so if we use SET_NEXT_STATE() >> to step back into SEND_REQUEST, our recv() call will likely fail with >> EAGAIN, once again blocking us until our next POLLOUT. Although the >> wasted syscall is not on the hot-path (after all, we can't progress >> until data arrives from the server), it's slightly cleaner if we >> instead declare that we are already blocked. >>
>> if (h->wlen) { >> if (h->in_write_payload) >> - SET_NEXT_STATE(%SEND_WRITE_PAYLOAD); >> + *next_state = %SEND_WRITE_PAYLOAD; >> else >> - SET_NEXT_STATE(%SEND_REQUEST); >> + *next_state = %SEND_REQUEST; > > It would be nice to do this without fiddling with essentially an > internal detail of the generated code. > > Could we add another macro, something like "SET_NEXT_STATE_AND_BLOCK"? Yes, that's a nice idea, and easy enough to squash in. > > On the other hand if it's not on the hot path, maybe we shouldn't > do this at all? It wasn't on the hot path on any test I could come up with (where we were waiting for the server anyway); but it may still be possible to come up with a scenario where it matters more. Should I push with this squashed in? diff --git i/generator/generator w/generator/generator index 34e70da..cbf4e59 100755 --- i/generator/generator +++ w/generator/generator @@ -2541,6 +2541,7 @@ let generate_lib_states_c () = pr "%s\n" state_machine_prologue; pr "\n"; pr "#define SET_NEXT_STATE(s) (*blocked = false, *next_state = (s))\n"; + pr "#define SET_NEXT_STATE_AND_BLOCK(s) (*next_state = (s))\n"; pr "\n"; (* The state machine C code fragments. *) diff --git i/generator/states-issue-command.c w/generator/states-issue-command.c index 9fc8c93..35f3c79 100644 --- i/generator/states-issue-command.c +++ w/generator/states-issue-command.c @@ -33,9 +33,9 @@ */ if (h->wlen) { if (h->in_write_payload) - *next_state = %SEND_WRITE_PAYLOAD; + SET_NEXT_STATE_AND_BLOCK (%SEND_WRITE_PAYLOAD); else - *next_state = %SEND_REQUEST; + SET_NEXT_STATE_AND_BLOCK (%SEND_REQUEST); return 0; } -- Eric Blake, Principal Software Engineer Red Hat, Inc. +1-919-301-3226 Virtualization: qemu.org | libvirt.org
signature.asc
Description: OpenPGP digital signature
_______________________________________________ Libguestfs mailing list Libguestfs@redhat.com https://www.redhat.com/mailman/listinfo/libguestfs