/* * Simply download a HTTP file. */ int main(int argc, char **argv) { CURL *http_handle; CURLM *multi_handle; int still_running; /* keep number of running handles */ int repeats = 0; CURLMsg *message; curl_global_init(CURL_GLOBAL_DEFAULT); http_handle = curl_easy_init(); /* set the options (I left out a few, you'll get the point anyway) */ curl_easy_setopt(http_handle, CURLOPT_URL, "http://www.example.com/"); multi_handle = curl_multi_init(); curl_multi_add_handle(multi_handle, http_handle); int i = curl_multi_perform(multi_handle, &still_running); do { CURLMcode mc; /* curl_multi_wait() return code */ int numfds; int pending; message = curl_multi_info_read(multi_handle, &pending); while (message != NULL) { printf ("%d is the pending\n", pending); message = curl_multi_info_read(multi_handle, &pending); } /* wait for activity, timeout or "nothing" */ mc = curl_multi_wait(multi_handle, NULL, 0, 1000, &numfds); printf ("%d - %d\n", mc, numfds); if(mc != CURLM_OK) { fprintf(stderr, "curl_multi_wait() failed, code %d.\n", mc); break; } /* 'numfds' being zero means either a timeout or no file descriptors to wait for. Try timeout on first occurrence, then assume no file descriptors and no file descriptors to wait for means wait for 100 milliseconds. */ if(!numfds) { repeats++; /* count number of repeated zero numfds */ if(repeats > 100) { WAITMS(100); /* sleep 100 milliseconds */ } } else repeats = 0; curl_multi_perform(multi_handle, &still_running); } while(still_running); curl_multi_remove_handle(multi_handle, http_handle); curl_easy_cleanup(http_handle); curl_multi_cleanup(multi_handle); curl_global_cleanup(); return 0; }
static void *pull_one_url(void *arg) { thread_info_t *thread_info = (thread_info_t *)arg; global_info_t *global_info = thread_info->global_info; work_info_t *work_info = NULL; int still_running; int ignore_sig[] = {SIGINT, SIGTERM}; pthread_set_ignore_sig(ignore_sig, sizeof(ignore_sig) / sizeof(int)); curl_easy_setopt(thread_info->curl, CURLOPT_WRITEFUNCTION, write_data); int repeats = 0; while (global_info->read_work_idx < global_info->work_num && !(global_info->do_exit)) { repeats = 0; DUMP("[%u:%lu]enter, read_work_idx: %u\n", thread_info->idx, time(NULL), global_info->read_work_idx); mutex_lock(global_info->rmtx); work_info = global_info->work_list[global_info->read_work_idx]; global_info->work_list[global_info->read_work_idx] = NULL; global_info->read_work_idx++; mutex_unlock(global_info->rmtx); DUMP("[%u:%lu]work %u, read_work_idx: %u\n", thread_info->idx, time(NULL), work_info->idx, global_info->read_work_idx); curl_easy_setopt(thread_info->curl, CURLOPT_WRITEDATA, work_info); curl_easy_setopt(thread_info->curl, CURLOPT_URL, work_info->url); int idx = 0; for (idx = 0; idx < global_info->round; ++idx) { curl_multi_add_handle(thread_info->multi_handle, thread_info->curl); curl_multi_perform(thread_info->multi_handle, &still_running); do { CURLMcode mc; /* curl_multi_wait() return code */ int numfds; /* wait for activity, timeout or "nothing" */ mc = curl_multi_wait(thread_info->multi_handle, NULL, 0, 1000, &numfds); if(mc != CURLM_OK) { fprintf(stderr, "curl_multi_fdset() failed, code %d.\n", mc); break; } /* 'numfds' being zero means either a timeout or no file descriptors to wait for. Try timeout on first occurance, then assume no file descriptors and no file descriptors to wait for means wait for 100 milliseconds. */ if(!numfds) { repeats++; /* count number of repeated zero numfds */ if(repeats > 1) { WAITMS(100); /* sleep 100 milliseconds */ } } else repeats = 0; curl_multi_perform(thread_info->multi_handle, &still_running); } while(still_running); curl_multi_remove_handle(thread_info->multi_handle, thread_info->curl); } DUMP("[%u:%lu]done %u, write_work_idx: %u\n", thread_info->idx, time(NULL), work_info->idx, global_info->write_work_idx); work_info->status = STAT_DONE; mutex_lock(global_info->wmtx); global_info->work_list[global_info->write_work_idx++] = work_info; mutex_unlock(global_info->wmtx); DUMP("[%u:%lu]out, write_work_idx: %u\n", thread_info->idx, time(NULL), global_info->write_work_idx); } return NULL; }