From 5fb4279ec7199e291d9bf4c903f89395f60a3d31 Mon Sep 17 00:00:00 2001 From: Dirk Manske Date: Thu, 30 Sep 2010 11:33:33 +0200 Subject: multi & hiper examples: updates and cleanups all multi and hiper examples: * don't loop curl_multi_perform calls, that was <7.20.0 style, currently the exported multi functions will not return CURLM_CALL_MULTI_PERFORM all hiper examples: * renamed check_run_count to check_multi_info * don't compare current running handle count with previous value, this was the wrong way to check for finished requests, simply call curl_multi_info_read * it's also safe to call curl_multi_remove_handle inside the curl_multi_info_read loop. ghiper.c: * replaced curl_multi_socket (that function is marked as obsolete) calls with curl_multi_socket_action calls (as in hiperfifo.c and evhiperfifo.c) ghiper.c and evhiperfifo.c: * be smart as hiperfifo.c, don't do uncessary curl_multi_* calls in new_conn and main --- docs/examples/ghiper.c | 103 ++++++++++++++++++++----------------------------- 1 file changed, 41 insertions(+), 62 deletions(-) (limited to 'docs/examples/ghiper.c') diff --git a/docs/examples/ghiper.c b/docs/examples/ghiper.c index 4f3913d71..ac11790cc 100644 --- a/docs/examples/ghiper.c +++ b/docs/examples/ghiper.c @@ -58,10 +58,7 @@ callback. typedef struct _GlobalInfo { CURLM *multi; guint timer_event; - int prev_running; int still_running; - int requested; /* count: curl_easy_init() */ - int completed; /* count: curl_easy_cleanup() */ } GlobalInfo; @@ -95,7 +92,6 @@ static void mcode_or_die(const char *where, CURLMcode code) { const char *s; switch (code) { case CURLM_CALL_MULTI_PERFORM: s="CURLM_CALL_MULTI_PERFORM"; break; - case CURLM_OK: s="CURLM_OK"; break; case CURLM_BAD_HANDLE: s="CURLM_BAD_HANDLE"; break; case CURLM_BAD_EASY_HANDLE: s="CURLM_BAD_EASY_HANDLE"; break; case CURLM_OUT_OF_MEMORY: s="CURLM_OUT_OF_MEMORY"; break; @@ -113,62 +109,43 @@ static void mcode_or_die(const char *where, CURLMcode code) { /* Check for completed transfers, and remove their easy handles */ -static void check_run_count(GlobalInfo *g) +static void check_multi_info(GlobalInfo *g) { - if (g->prev_running > g->still_running) { - char *eff_url=NULL; - CURLMsg *msg; - int msgs_left; - ConnInfo *conn=NULL; - CURL*easy; - CURLcode res; - - MSG_OUT("REMAINING: %d\n", g->still_running); - /* - I am still uncertain whether it is safe to remove an easy handle - from inside the curl_multi_info_read loop, so here I will search - for completed transfers in the inner "while" loop, and then remove - them in the outer "do-while" loop... - */ - do { - easy=NULL; - while ((msg = curl_multi_info_read(g->multi, &msgs_left))) { - if (msg->msg == CURLMSG_DONE) { - easy=msg->easy_handle; - res=msg->data.result; - break; - } - } - if (easy) { - curl_easy_getinfo(easy, CURLINFO_PRIVATE, &conn); - curl_easy_getinfo(easy, CURLINFO_EFFECTIVE_URL, &eff_url); - MSG_OUT("DONE: %s => (%d) %s\n", eff_url, res, conn->error); - curl_multi_remove_handle(g->multi, easy); - g_free(conn->url); - curl_easy_cleanup(easy); - g_free(conn); - g->completed++; - } - } while ( easy ); - MSG_OUT("Requested: %d Completed:%d\n", g->requested, g->completed); + char *eff_url; + CURLMsg *msg; + int msgs_left; + ConnInfo *conn; + CURL *easy; + CURLcode res; + + MSG_OUT("REMAINING: %d\n", g->still_running); + while ((msg = curl_multi_info_read(g->multi, &msgs_left))) { + if (msg->msg == CURLMSG_DONE) { + easy = msg->easy_handle; + res = msg->data.result; + curl_easy_getinfo(easy, CURLINFO_PRIVATE, &conn); + curl_easy_getinfo(easy, CURLINFO_EFFECTIVE_URL, &eff_url); + MSG_OUT("DONE: %s => (%d) %s\n", eff_url, res, conn->error); + curl_multi_remove_handle(g->multi, easy); + free(conn->url); + curl_easy_cleanup(easy); + free(conn); + } } - g->prev_running = g->still_running; } - /* Called by glib when our timeout expires */ static gboolean timer_cb(gpointer data) { GlobalInfo *g = (GlobalInfo *)data; CURLMcode rc; - do { - rc = curl_multi_socket(g->multi, CURL_SOCKET_TIMEOUT, &g->still_running); - } while (rc == CURLM_CALL_MULTI_PERFORM); - mcode_or_die("timer_cb: curl_multi_socket", rc); - check_run_count(g); + rc = curl_multi_socket_action(g->multi, + CURL_SOCKET_TIMEOUT, 0, &g->still_running); + mcode_or_die("timer_cb: curl_multi_socket_action", rc); + check_multi_info(g); return FALSE; } @@ -198,11 +175,15 @@ static gboolean event_cb(GIOChannel *ch, GIOCondition condition, gpointer data) GlobalInfo *g = (GlobalInfo*) data; CURLMcode rc; int fd=g_io_channel_unix_get_fd(ch); - do { - rc = curl_multi_socket(g->multi, fd, &g->still_running); - } while (rc == CURLM_CALL_MULTI_PERFORM); - mcode_or_die("event_cb: curl_multi_socket", rc); - check_run_count(g); + + int action = + (condition & G_IO_IN ? CURL_CSELECT_IN : 0) | + (condition & G_IO_OUT ? CURL_CSELECT_OUT : 0); + + rc = curl_multi_socket_action(g->multi, fd, action, &g->still_running); + mcode_or_die("event_cb: curl_multi_socket_action", rc); + + check_multi_info(g); if(g->still_running) { return TRUE; } else { @@ -338,12 +319,9 @@ static void new_conn(char *url, GlobalInfo *g ) MSG_OUT("Adding easy %p to multi %p (%s)\n", conn->easy, g->multi, url); rc =curl_multi_add_handle(g->multi, conn->easy); mcode_or_die("new_conn: curl_multi_add_handle", rc); - g->requested++; - do { - rc = curl_multi_socket_all(g->multi, &g->still_running); - } while (CURLM_CALL_MULTI_PERFORM == rc); - mcode_or_die("new_conn: curl_multi_socket_all", rc); - check_run_count(g); + + /* note that the add_handle() will set a time-out to trigger very soon so + that the necessary socket_action() call will be called by this app */ } @@ -451,9 +429,10 @@ int main(int argc, char **argv) curl_multi_setopt(g->multi, CURLMOPT_SOCKETDATA, g); curl_multi_setopt(g->multi, CURLMOPT_TIMERFUNCTION, update_timeout_cb); curl_multi_setopt(g->multi, CURLMOPT_TIMERDATA, g); - do { - rc = curl_multi_socket_all(g->multi, &g->still_running); - } while (CURLM_CALL_MULTI_PERFORM == rc); + + /* we don't call any curl_multi_socket*() function yet as we have no handles + added! */ + g_main_loop_run(gmain); curl_multi_cleanup(g->multi); return 0; -- cgit v1.2.3