Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C libcurl, limit download speed - cpu usage goes 100%

Tags:

c++

c

libcurl

I have problem with CURLOPT_MAX_RECV_SPEED_LARGE api man page.

I want to set max download speed, so i added:

curl_off_t max_speed = 1000*25;
curl_easy_setopt(curl_handle, CURLOPT_MAX_RECV_SPEED_LARGE, max_speed);

But problem is when it hit the limit (25kB/s) or what I set up, the CPU usage goes 100%

Am I using it wrong way? I guess, because I haven't find this problem anywhere. I tried to add these two lines into original sample code, but it also go crazy.

I am using Windows and libcurl v 7.29

Thanks

Possible solution would be to write your own kind of sleep in progress function, but ...

Here is original code "getinmemory.c", with my 2 added lines:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <curl/curl.h>

struct MemoryStruct {
  char *memory;
  size_t size;
};


static size_t WriteMemoryCallback(void *contents, size_t size, size_t nmemb, void     *userp)
{
  size_t realsize = size * nmemb;
  struct MemoryStruct *mem = (struct MemoryStruct *)userp;

  mem->memory =(char*) realloc(mem->memory, mem->size + realsize + 1);
  if(mem->memory == NULL) {
    /* out of memory! */
    printf("not enough memory (realloc returned NULL)\n");
    return 0;
  }

  memcpy(&(mem->memory[mem->size]), contents, realsize);
  mem->size += realsize;
  mem->memory[mem->size] = 0;

  return realsize;
}


int main(void)
{
  CURL *curl_handle;
  CURLcode res;

  struct MemoryStruct chunk;

  chunk.memory = (char*)malloc(1);  /* will be grown as needed by the realloc     above */
  chunk.size = 0;    /* no data at this point */

  curl_global_init(CURL_GLOBAL_ALL);

  curl_handle = curl_easy_init();

  curl_easy_setopt(curl_handle, CURLOPT_URL,     "http://ns223506.ovh.net/rozne/04e4383e647ce87ce42e73fa00bb0058/wallpaper-812988.jpg");   //Random wallpaper
  curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, WriteMemoryCallback);
  curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, (void *)&chunk);
  curl_easy_setopt(curl_handle, CURLOPT_USERAGENT, "libcurl-agent/1.0");

  //My added 2 lines
  curl_off_t max_speed = 1000*25; // 25kB/s
  curl_easy_setopt(curl_handle, CURLOPT_MAX_RECV_SPEED_LARGE, max_speed);


  res = curl_easy_perform(curl_handle);

  if(res != CURLE_OK) {
    fprintf(stderr, "curl_easy_perform() failed: %s\n",
            curl_easy_strerror(res));
  }
  else {
    printf("%lu bytes retrieved\n", (long)chunk.size);
  }

  curl_easy_cleanup(curl_handle);

  if(chunk.memory)
    free(chunk.memory);

   curl_global_cleanup();

  return 0;
}
like image 548
pagep Avatar asked Jun 25 '13 21:06

pagep


2 Answers

Ok PROBLEM SOLVED

It only occurs in version curl-7.29.0-devel-mingw32 !

Versions

  • curl-7.26.0-devel-mingw32
  • curl-7.31.0-devel-mingw32

are OK

I tested another version before, but I wasn't copying dlls into right folder and I didn't check directly in program using curl_version(); sorry :(

like image 197
pagep Avatar answered Nov 15 '22 05:11

pagep


This would appear to be an issue with the way you are reading data. By limiting the download speed, you appear to be causing the act of downloading the image to be bound by the bandwidth of receiving the data. As a result, the CPU doesn't have the data it wants and is continously polling until it receives all the data from the download.

In such a scenario, there is nothing putting the process waiting for the data to sleep, so it sits there chewing up CPU.

like image 39
It'sPete Avatar answered Nov 15 '22 05:11

It'sPete