cURL / Mailing Lists / curl-library / Single Mail

curl-library

RE: libcurl and async I/O

From: Andrew Barnert <abarnert_at_adobe.com>
Date: Mon, 18 Aug 2008 20:16:25 -0700

18 Aug 2008 19:10, Jamie Lokier:
> Andrew Barnert wrote:
[snip]
> All the more reason to have code patterns which can adapt both ways
> around, to join each style of code together.

Well, yes, but I'm not sure how you can easily adapt a socket-wrapper
library to async I/O if it wasn't written for it. A library that expects
real fds and calls recv/send on them (much less one that calls select)
is pretty hard to adapt from outside.

(I'll grant that it's not actually impossible to intercept send and
recv. You can always interpose your own replacement functions in
front of the OS with a DLL/so, or rebuild OpenSSL with send #define'd
to my_send_wrapper, or whatever. But I don't think that's the
answer here.)

> > I'm not sure I agree. Even forgetting about SSL/SSH/Kerb, the socket
> > callback is going to need the buffer to be read/written so it can
> > make the async read/write call. That means either exposing internal
> > info about how the connectdata, SingleRequest, etc. structs work,
> > changing things so that the app manages the buffers instead of libcurl,
> > or putting the buffers into the API.
>
> Or do some data copying, and simulate an epoll-style API for curl's
> benefit. I.e. pretend socket is "ready for write", let curl write,
> you start an async write and pretend its not ready any more, until
> that async write finishes. (Or overlap a few more, as you like.)
> Similar for reading.

But when you "let curl write," it does that by calling send directly
on the fd, and only calls out to the application when the write is
finished. There's no way to intercept the send and turn it into an
async write. And after the write's completed, and libcurl calls the
callback to ask you to notify it for write, we have no data to do an
async write with (and, even if we did, curl doesn't tell us what the
data is).

So, you need to change the API. The smallest change, I guess, would
be to allow the application to pass in its own custom send and recv
functions for curl to use, but changing it the way I originally
suggested isn't that much bigger, and it doesn't require you to
fake poll on top of asio.

In fact, the API that I suggested could be used for both ways of
doing I/O equally well; the only reason I suggested adding new
functions instead of changing the old ones is to avoid breaking
existing code.

By the way, I'm not sure if I mentioned this before, but faking
asio on top of a poll-type API is trivial and actually pretty
efficient, while the other way around (basically what you suggested)
is more complicated and measurably slow. If you're really going to
force one or the other, forcing asio makes more sense. But if you
can write an API that works either way, that's by far a better
solution.

And you can. And, as I said, libcurl is actually pretty close.
Received on 2008-08-19