|
|
@@ -0,0 +1,190 @@
|
|
|
+#ifndef __CURL_MULTI_H
|
|
|
+#define __CURL_MULTI_H
|
|
|
+/***************************************************************************
|
|
|
+ * _ _ ____ _
|
|
|
+ * Project ___| | | | _ \| |
|
|
|
+ * / __| | | | |_) | |
|
|
|
+ * | (__| |_| | _ <| |___
|
|
|
+ * \___|\___/|_| \_\_____|
|
|
|
+ *
|
|
|
+ * Copyright (C) 1998 - 2002, Daniel Stenberg, <[email protected]>, et al.
|
|
|
+ *
|
|
|
+ * This software is licensed as described in the file COPYING, which
|
|
|
+ * you should have received as part of this distribution. The terms
|
|
|
+ * are also available at http://curl.haxx.se/docs/copyright.html.
|
|
|
+ *
|
|
|
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
|
|
+ * copies of the Software, and permit persons to whom the Software is
|
|
|
+ * furnished to do so, under the terms of the COPYING file.
|
|
|
+ *
|
|
|
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
|
|
+ * KIND, either express or implied.
|
|
|
+ *
|
|
|
+ * $Id$
|
|
|
+ ***************************************************************************/
|
|
|
+/*
|
|
|
+ This is meant to be the "external" header file. Don't give away any
|
|
|
+ internals here!
|
|
|
+
|
|
|
+ This document presents a mixture of ideas from at least:
|
|
|
+ - Daniel Stenberg
|
|
|
+ - Steve Dekorte
|
|
|
+ - Sterling Hughes
|
|
|
+ - Ben Greear
|
|
|
+
|
|
|
+ -------------------------------------------
|
|
|
+ GOALS
|
|
|
+
|
|
|
+ o Enable a "pull" interface. The application that uses libcurl decides where
|
|
|
+ and when to ask libcurl to get/send data.
|
|
|
+
|
|
|
+ o Enable multiple simultaneous transfers in the same thread without making it
|
|
|
+ complicated for the application.
|
|
|
+
|
|
|
+ o Enable the application to select() on its own file descriptors and curl's
|
|
|
+ file descriptors simultaneous easily.
|
|
|
+
|
|
|
+ Example sources using this interface is here: ../multi/
|
|
|
+
|
|
|
+*/
|
|
|
+
|
|
|
+#if defined(WIN32) && !defined(__GNUC__) || defined(__MINGW32__)
|
|
|
+#include <winsock.h>
|
|
|
+#else
|
|
|
+#include <sys/socket.h>
|
|
|
+#include <sys/time.h>
|
|
|
+#endif
|
|
|
+
|
|
|
+#include "curl.h"
|
|
|
+
|
|
|
+typedef void CURLM;
|
|
|
+
|
|
|
+typedef enum {
|
|
|
+ CURLM_CALL_MULTI_PERFORM=-1, /* please call curl_multi_perform() soon */
|
|
|
+ CURLM_OK,
|
|
|
+ CURLM_BAD_HANDLE, /* the passed-in handle is not a valid CURLM handle */
|
|
|
+ CURLM_BAD_EASY_HANDLE, /* an easy handle was not good/valid */
|
|
|
+ CURLM_OUT_OF_MEMORY, /* if you ever get this, you're in deep sh*t */
|
|
|
+ CURLM_INTERNAL_ERROR, /* this is a libcurl bug */
|
|
|
+ CURLM_LAST
|
|
|
+} CURLMcode;
|
|
|
+
|
|
|
+typedef enum {
|
|
|
+ CURLMSG_NONE, /* first, not used */
|
|
|
+ CURLMSG_DONE, /* This easy handle has completed. 'whatever' points to
|
|
|
+ the CURLcode of the transfer */
|
|
|
+ CURLMSG_LAST /* last, not used */
|
|
|
+} CURLMSG;
|
|
|
+
|
|
|
+struct CURLMsg {
|
|
|
+ CURLMSG msg; /* what this message means */
|
|
|
+ CURL *easy_handle; /* the handle it concerns */
|
|
|
+ union {
|
|
|
+ void *whatever; /* message-specific data */
|
|
|
+ CURLcode result; /* return code for transfer */
|
|
|
+ } data;
|
|
|
+};
|
|
|
+typedef struct CURLMsg CURLMsg;
|
|
|
+
|
|
|
+/*
|
|
|
+ * Name: curl_multi_init()
|
|
|
+ *
|
|
|
+ * Desc: inititalize multi-style curl usage
|
|
|
+ * Returns: a new CURLM handle to use in all 'curl_multi' functions.
|
|
|
+ */
|
|
|
+CURLM *curl_multi_init(void);
|
|
|
+
|
|
|
+/*
|
|
|
+ * Name: curl_multi_add_handle()
|
|
|
+ *
|
|
|
+ * Desc: add a standard curl handle to the multi stack
|
|
|
+ * Returns: CURLMcode type, general multi error code.
|
|
|
+ */
|
|
|
+CURLMcode curl_multi_add_handle(CURLM *multi_handle,
|
|
|
+ CURL *curl_handle);
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Name: curl_multi_remove_handle()
|
|
|
+ *
|
|
|
+ * Desc: removes a curl handle from the multi stack again
|
|
|
+ * Returns: CURLMcode type, general multi error code.
|
|
|
+ */
|
|
|
+CURLMcode curl_multi_remove_handle(CURLM *multi_handle,
|
|
|
+ CURL *curl_handle);
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Name: curl_multi_fdset()
|
|
|
+ *
|
|
|
+ * Desc: Ask curl for its fd_set sets. The app can use these to select() or
|
|
|
+ * poll() on. We want curl_multi_perform() called as soon as one of
|
|
|
+ * them are ready.
|
|
|
+ * Returns: CURLMcode type, general multi error code.
|
|
|
+ */
|
|
|
+CURLMcode curl_multi_fdset(CURLM *multi_handle,
|
|
|
+ fd_set *read_fd_set,
|
|
|
+ fd_set *write_fd_set,
|
|
|
+ fd_set *exc_fd_set,
|
|
|
+ int *max_fd);
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Name: curl_multi_perform()
|
|
|
+ *
|
|
|
+ * Desc: When the app thinks there's data available for curl it calls this
|
|
|
+ * function to read/write whatever there is right now. This returns
|
|
|
+ * as soon as the reads and writes are done. This function does not
|
|
|
+ * require that there actually is data available for reading or that
|
|
|
+ * data can be written, it can be called just in case. It returns
|
|
|
+ * the number of handles that still transfer data in the second
|
|
|
+ * argument's integer-pointer.
|
|
|
+ *
|
|
|
+ * Returns: CURLMcode type, general multi error code. *NOTE* that this only
|
|
|
+ * returns errors etc regarding the whole multi stack. There might
|
|
|
+ * still have occurred problems on invidual transfers even when this
|
|
|
+ * returns OK.
|
|
|
+ */
|
|
|
+CURLMcode curl_multi_perform(CURLM *multi_handle,
|
|
|
+ int *running_handles);
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Name: curl_multi_cleanup()
|
|
|
+ *
|
|
|
+ * Desc: Cleans up and removes a whole multi stack. It does not free or
|
|
|
+ * touch any individual easy handles in any way. We need to define
|
|
|
+ * in what state those handles will be if this function is called
|
|
|
+ * in the middle of a transfer.
|
|
|
+ * Returns: CURLMcode type, general multi error code.
|
|
|
+ */
|
|
|
+CURLMcode curl_multi_cleanup(CURLM *multi_handle);
|
|
|
+
|
|
|
+/*
|
|
|
+ * Name: curl_multi_info_read()
|
|
|
+ *
|
|
|
+ * Desc: Ask the multi handle if there's any messages/informationals from
|
|
|
+ * the individual transfers. Messages include informationals such as
|
|
|
+ * error code from the transfer or just the fact that a transfer is
|
|
|
+ * completed. More details on these should be written down as well.
|
|
|
+ *
|
|
|
+ * Repeated calls to this function will return a new struct each
|
|
|
+ * time, until a special "end of msgs" struct is returned as a signal
|
|
|
+ * that there is no more to get at this point.
|
|
|
+ *
|
|
|
+ * The data the returned pointer points to will not survive calling
|
|
|
+ * curl_multi_cleanup().
|
|
|
+ *
|
|
|
+ * The 'CURLMsg' struct is meant to be very simple and only contain
|
|
|
+ * very basic informations. If more involved information is wanted,
|
|
|
+ * we will provide the particular "transfer handle" in that struct
|
|
|
+ * and that should/could/would be used in subsequent
|
|
|
+ * curl_easy_getinfo() calls (or similar). The point being that we
|
|
|
+ * must never expose complex structs to applications, as then we'll
|
|
|
+ * undoubtably get backwards compatibility problems in the future.
|
|
|
+ *
|
|
|
+ * Returns: A pointer to a filled-in struct, or NULL if it failed or ran out
|
|
|
+ * of structs. It also writes the number of messages left in the
|
|
|
+ * queue (after this read) in the integer the second argument points
|
|
|
+ * to.
|
|
|
+ */
|
|
|
+CURLMsg *curl_multi_info_read(CURLM *multi_handle,
|
|
|
+ int *msgs_in_queue);
|
|
|
+
|
|
|
+#endif
|