libcurl docs: improvements all over
This commit is contained in:
@@ -5,7 +5,7 @@
|
||||
.\" * | (__| |_| | _ <| |___
|
||||
.\" * \___|\___/|_| \_\_____|
|
||||
.\" *
|
||||
.\" * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
.\" * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
.\" *
|
||||
.\" * This software is licensed as described in the file COPYING, which
|
||||
.\" * you should have received as part of this distribution. The terms
|
||||
@@ -20,7 +20,7 @@
|
||||
.\" *
|
||||
.\" **************************************************************************
|
||||
.\"
|
||||
.TH libcurl-multi 3 "3 Feb 2007" "libcurl 7.16.0" "libcurl multi interface"
|
||||
.TH libcurl-multi 3 "19 Sep 2014" "libcurl" "libcurl multi interface"
|
||||
.SH NAME
|
||||
libcurl-multi \- how to use the multi interface
|
||||
.SH DESCRIPTION
|
||||
@@ -43,18 +43,28 @@ complicated for the application.
|
||||
|
||||
3. Enable the application to wait for action on its own file descriptors and
|
||||
curl's file descriptors simultaneous easily.
|
||||
|
||||
4. Enable event-based handling and scaling transfers up to and beyond
|
||||
thousands of parallel connections.
|
||||
.SH "ONE MULTI HANDLE MANY EASY HANDLES"
|
||||
To use the multi interface, you must first create a 'multi handle' with
|
||||
\fIcurl_multi_init(3)\fP. This handle is then used as input to all further
|
||||
curl_multi_* functions.
|
||||
|
||||
Each single transfer is built up with an easy handle. You must create them,
|
||||
and setup the appropriate options for each easy handle, as outlined in the
|
||||
\fIlibcurl(3)\fP man page, using \fIcurl_easy_setopt(3)\fP.
|
||||
With a multi handle and the multi interface you can do any amount of
|
||||
simultaneous transfers in parallel. Each single transfer is built up around an
|
||||
easy handle. You must create the easy handles you need, and setup the
|
||||
appropriate options for each easy handle, as outlined in the \fIlibcurl(3)\fP
|
||||
man page, using \fIcurl_easy_setopt(3)\fP.
|
||||
|
||||
When the easy handle is setup for a transfer, then instead of using
|
||||
\fIcurl_easy_perform(3)\fP (as when using the easy interface for transfers),
|
||||
you should instead add the easy handle to the multi handle using
|
||||
There are two flavours of the multi interface, the select() oriented one and
|
||||
the event based one we called multi_socket. You will benefit from reading
|
||||
through the description of both versions to full understand how they work and
|
||||
differentiate. We start out with the select() oriented version.
|
||||
|
||||
When an easy handle is setup for a transfer, then instead of using
|
||||
\fIcurl_easy_perform(3)\fP like when using the easy interface for transfers,
|
||||
you should add the easy handle to the multi handle with
|
||||
\fIcurl_multi_add_handle(3)\fP. The multi handle is sometimes referred to as a
|
||||
\'multi stack\' because of the fact that it may hold a large amount of easy
|
||||
handles.
|
||||
@@ -71,7 +81,8 @@ application drive. You drive the transfers by invoking
|
||||
anything available to transfer. It'll use the callbacks and everything else
|
||||
you have setup in the individual easy handles. It'll transfer data on all
|
||||
current transfers in the multi stack that are ready to transfer anything. It
|
||||
may be all, it may be none.
|
||||
may be all, it may be none. When there's nothing more to do for now, it
|
||||
returns back to the calling application.
|
||||
|
||||
Your application can acquire knowledge from libcurl when it would like to get
|
||||
invoked to transfer data, so that you don't have to busy-loop and call that
|
||||
@@ -80,7 +91,9 @@ interface using which you can extract fd_sets from libcurl to use in select()
|
||||
or poll() calls in order to get to know when the transfers in the multi stack
|
||||
might need attention. This also makes it very easy for your program to wait
|
||||
for input on your own private file descriptors at the same time or perhaps
|
||||
timeout every now and then, should you want that.
|
||||
timeout every now and then, should you want that. \fIcurl_multi_timeout(3)\fP
|
||||
also helps you with providing a suitable timeout period for your select()
|
||||
call.
|
||||
|
||||
\fIcurl_multi_perform(3)\fP stores the number of still running transfers in
|
||||
one of its input arguments, and by reading that you can figure out when all
|
||||
@@ -121,21 +134,39 @@ using large numbers of simultaneous connections.
|
||||
When using this API, you add easy handles to the multi handle just as with the
|
||||
normal multi interface. Then you also set two callbacks with the
|
||||
CURLMOPT_SOCKETFUNCTION and CURLMOPT_TIMERFUNCTION options to
|
||||
\fIcurl_multi_setopt(3)\fP.
|
||||
\fIcurl_multi_setopt(3)\fP. They are two callback functions that libcurl will
|
||||
call with information about what sockets to wait for, and for what activity,
|
||||
and what the curret timeout time is - if that expires libcurl should be
|
||||
notified.
|
||||
|
||||
The API is then designed to inform your application about which sockets
|
||||
libcurl is currently using and for what activities (read and/or write) on
|
||||
those sockets your application is expected to wait for.
|
||||
The multi_socket API is designed to inform your application about which
|
||||
sockets libcurl is currently using and for what activities (read and/or write)
|
||||
on those sockets your application is expected to wait for.
|
||||
|
||||
Your application must then make sure to receive all sockets informed about in
|
||||
the CURLMOPT_SOCKETFUNCTION callback and make sure it reacts on the given
|
||||
activity on them. When a socket has the given activity, you call
|
||||
Your application must make sure to receive all sockets informed about in the
|
||||
CURLMOPT_SOCKETFUNCTION callback and make sure it reacts on the given activity
|
||||
on them. When a socket has the given activity, you call
|
||||
\fIcurl_multi_socket_action(3)\fP specifying which socket and action there
|
||||
are.
|
||||
|
||||
The CURLMOPT_TIMERFUNCTION callback is called to set a timeout. When that
|
||||
timeout expires, your application should call the
|
||||
\fIcurl_multi_socket_action(3)\fP function saying it was due to a timeout.
|
||||
|
||||
This API is typically used with an event-driven underlying functionality (like
|
||||
libevent, libev, kqueue, epoll or similar) which which the application
|
||||
"subscribes" on socket changes. This allows applications and libcurl to much
|
||||
better scale upward and beyond thousands of simultaneous transfers without
|
||||
losing performance.
|
||||
|
||||
When you've added your initial set of handles, you call
|
||||
\fIcurl_multi_socket_action(3)\fP with CURL_SOCKET_TIMEOUT set in the sockfd
|
||||
argument, and you'll get callbacks call that sets you up and you then continue
|
||||
to call \fIcurl_multi_socket_action(3)\fP accordingly when you get activity on
|
||||
the sockets you've been asked to wait on, or if the timeout timer expires.
|
||||
|
||||
You can poll \fIcurl_multi_info_read(3)\fP to see if any transfer has
|
||||
completed, as it then has a message saying so.
|
||||
.SH "BLOCKING"
|
||||
A few areas in the code are still using blocking code, even when used from the
|
||||
multi interface. While we certainly want and intend for these to get fixed in
|
||||
|
Reference in New Issue
Block a user