On Thu, Jun 05, 2014 at 11:27:49AM +0200, Paolo Bonzini wrote: > Il 05/06/2014 10:12, Stefan Hajnoczi ha scritto: > >On Wed, Jun 04, 2014 at 08:02:06PM +0200, Paolo Bonzini wrote: > >>Il 04/06/2014 14:37, Stefan Hajnoczi ha scritto: > >>>Why is this design cleaner? Because NBD code doesn't have to worry > >>>about fd handlers. It uses straightforward coroutine send/recv for > >>>socket I/O inside nbd_read_req() and nbd_write_resp(). It's easy to see > >>>that only one coroutine receives from the socket and that only one > >>>coroutine writes to the socket. > >> > >>I don't understand how this would work without managing fd handlers. > > > >fd handlers still need to be managed, but not by NBD code. They must be > >managed by coroutine recv/send utility functions. In other words, fd > >handlers are used locally, not globally. > > > >def co_recv(fd, buf): > > while True: > > nbytes = recv(fd, buf, len(buf)) > > if nbytes == -1: > > if errno == EINTR: > > continue > > if errno == EAGAIN or errno == EWOULDBLOCK: > > aio_set_fd_read_handler(fd, co_recv_cb) > > qemu_coroutine_yield() > > aio_set_fd_read_handler(fd, NULL) > > continue > > return nbytes > > > >The send function is similar. > > I see what you mean now---this however is not how qemu_co_recv and > qemu_co_send work. NBD uses them, but they require the caller to set up the > handlers manually.
Yep, and I think that's not a clean way to program since it forgoes the advantage of coroutines: functions that look just like their blocking equivalents. I think we should hide the fd handler management so coroutine socket users don't need to worry about it. Stefan