cURL / Mailing Lists / curl-library / Single Mail

curl-library

Re: [patch] preliminary high_speed_limit patch

From: Peter <peter_at_bsqt.homeip.net>
Date: Thu, 15 Jun 2006 23:08:36 -0400

patch promised in previous letter.

algorithm: removes offending fd from ''select'' set when over speed.
no sleep needed because of 1 second timeout on select. uses Curl_pgrsUpdate
calculated average upload and download speed to make the decision.

-- Doesn't require an other patches so far submitted.
-- diff created from updated cvs anonymous checkout.
-- adds implementation of --limit-rate in library.
-- replaces --limit-rate implementation with new library based one.

seems to work fine. the multi version not adequately tested, but since
there was none before, this should not break anything.
passes all the same tests that passed before the change.

hope this can be accepted...

diff -cr --exclude CVS --exclude autom4te.cache curl/include/curl/curl.h curl_liblimitrate/include/curl/curl.h
*** curl/include/curl/curl.h Mon Jun 12 16:33:05 2006
--- curl_liblimitrate/include/curl/curl.h Thu Jun 15 21:11:38 2006
***************
*** 973,978 ****
--- 973,983 ----
       Note that this is used only for SSL certificate processing */
    CINIT(CONV_FROM_UTF8_FUNCTION, FUNCTIONPOINT, 144),

+ /* if the connection proceeds too quickly then need to slow it down */
+ /* limit-rate: maximum number of bytes per second to send or receive */
+ CINIT(MAX_SEND_PER_SECOND, LONG, 142),
+ CINIT(MAX_RECV_PER_SECOND, LONG, 143),
+
    CURLOPT_LASTENTRY /* the last unused */
  } CURLoption;

diff -cr --exclude CVS --exclude autom4te.cache curl/lib/multi.c curl_liblimitrate/lib/multi.c
*** curl/lib/multi.c Sat May 27 18:26:16 2006
--- curl_liblimitrate/lib/multi.c Thu Jun 15 21:51:31 2006
***************
*** 68,73 ****
--- 68,74 ----
    CURLM_STATE_DOING, /* sending off the request (part 1) */
    CURLM_STATE_DO_MORE, /* send off the request (part 2) */
    CURLM_STATE_PERFORM, /* transfer data */
+ CURLM_STATE_TOOFAST, /* wait because limit-rate exceeded */
    CURLM_STATE_DONE, /* post data transfer operation */
    CURLM_STATE_COMPLETED, /* operation complete */

***************
*** 440,445 ****
--- 441,447 ----
                           int numsocks)
  {
    switch(easy->state) {
+ /* FIXME assumption CURLM_STATE_TOOFAST returns 0, so will not select. */
    default:
      return 0;

***************
*** 771,777 ****
        }
        break;

! case CURLM_STATE_PERFORM:
        /* read/write data if it is ready to do so */
        easy->result = Curl_readwrite(easy->easy_conn, &done);

--- 773,804 ----
        }
        break;

!
! case CURLM_STATE_TOOFAST: /* limit-rate exceeded in either direction.., watch. */
!
! /* if both rates are within spec, resume transfer */
! Curl_pgrsUpdate(easy->easy_conn);
! if ( ( ( easy->easy_handle->set.max_send_per_second == 0 ) ||
! ( easy->easy_handle->progress.ulspeed < easy->easy_handle->set.max_send_per_second ) ) &&
! ( ( easy->easy_handle->set.max_recv_per_second == 0 ) ||
! ( easy->easy_handle->progress.dlspeed < easy->easy_handle->set.max_recv_per_second ) )
! ) {
! multistate(easy, CURLM_STATE_PERFORM);
! };
! break;
!
! case CURLM_STATE_PERFORM:
!
! /* check if over speed */
! if ( ( ( easy->easy_handle->set.max_send_per_second > 0 ) &&
! ( easy->easy_handle->progress.ulspeed > easy->easy_handle->set.max_send_per_second ) ) ||
! ( ( easy->easy_handle->set.max_recv_per_second > 0 ) &&
! ( easy->easy_handle->progress.dlspeed > easy->easy_handle->set.max_recv_per_second ) )
! ) {
! multistate(easy, CURLM_STATE_TOOFAST );
! break;
! };
!
        /* read/write data if it is ready to do so */
        easy->result = Curl_readwrite(easy->easy_conn, &done);

***************
*** 825,830 ****
--- 852,858 ----
          }
        }
        break;
+
      case CURLM_STATE_DONE:
        /* post-transfer command */
        easy->result = Curl_done(&easy->easy_conn, CURLE_OK);
diff -cr --exclude CVS --exclude autom4te.cache curl/lib/progress.c curl_liblimitrate/lib/progress.c
*** curl/lib/progress.c Fri Nov 26 09:33:14 2004
--- curl_liblimitrate/lib/progress.c Thu Jun 15 21:11:20 2006
***************
*** 343,348 ****
--- 343,349 ----
        (data->progress.ulspeed>data->progress.dlspeed)?
        data->progress.ulspeed:data->progress.dlspeed;

+
    if(data->progress.flags & PGRS_HIDE)
      return 0;

diff -cr --exclude CVS --exclude autom4te.cache curl/lib/transfer.c curl_liblimitrate/lib/transfer.c
*** curl/lib/transfer.c Thu Jun 15 21:12:51 2006
--- curl_liblimitrate/lib/transfer.c Thu Jun 15 21:11:30 2006
***************
*** 1628,1642 ****

      interval_ms = 1 * 1000;

! if(k->keepon & KEEP_READ)
! fd_read = conn->sockfd;
! else
! fd_read = CURL_SOCKET_BAD;
!
! if(k->keepon & KEEP_WRITE)
! fd_write = conn->writesockfd;
! else
! fd_write = CURL_SOCKET_BAD;

      switch (Curl_select(fd_read, fd_write, interval_ms)) {
      case -1: /* select() error, stop reading */
--- 1628,1655 ----

      interval_ms = 1 * 1000;

! /* limit-rate logic: if speed exceeds threshold, then do not include fd in select set */
! if ( ( conn->data->set.max_send_per_second > 0 ) &&
! ( (curl_off_t)conn->data->progress.ulspeed > conn->data->set.max_send_per_second ) ) {
! fd_write = CURL_SOCKET_BAD;
! Curl_pgrsUpdate(conn);
! } else {
! if(k->keepon & KEEP_WRITE)
! fd_write = conn->writesockfd;
! else
! fd_write = CURL_SOCKET_BAD;
! }
!
! if ( ( conn->data->set.max_recv_per_second > 0 ) &&
! ( (curl_off_t)conn->data->progress.dlspeed > conn->data->set.max_recv_per_second ) ) {
! fd_read = CURL_SOCKET_BAD;
! Curl_pgrsUpdate(conn);
! } else {
! if(k->keepon & KEEP_READ)
! fd_read = conn->sockfd;
! else
! fd_read = CURL_SOCKET_BAD;
! }

      switch (Curl_select(fd_read, fd_write, interval_ms)) {
      case -1: /* select() error, stop reading */
***************
*** 1651,1656 ****
--- 1664,1670 ----
        continue;
      case 0: /* timeout */
      default: /* readable descriptors */
+
        result = Curl_readwrite(conn, &done);
        break;
      }
diff -cr --exclude CVS --exclude autom4te.cache curl/lib/url.c curl_liblimitrate/lib/url.c
*** curl/lib/url.c Thu Jun 8 02:12:31 2006
--- curl_liblimitrate/lib/url.c Thu Jun 15 21:11:24 2006
***************
*** 1039,1044 ****
--- 1039,1058 ----
       */
      data->set.low_speed_limit=va_arg(param, long);
      break;
+ case CURLOPT_MAX_SEND_PER_SECOND:
+ /*
+ * The max speed limit that sends transfer more than
+ * CURLOPT_MAX_SEND_PER_SECOND bytes per second the transfer is throttled..
+ */
+ data->set.max_send_per_second=va_arg(param, long);
+ break;
+ case CURLOPT_MAX_RECV_PER_SECOND:
+ /*
+ * The max speed limit that sends transfer more than
+ * CURLOPT_MAX_RECV_PER_SECOND bytes per second the transfer is throttled..
+ */
+ data->set.max_recv_per_second=va_arg(param, long);
+ break;
    case CURLOPT_LOW_SPEED_TIME:
      /*
       * The low speed time that if transfers are below the set
diff -cr --exclude CVS --exclude autom4te.cache curl/lib/urldata.h curl_liblimitrate/lib/urldata.h
*** curl/lib/urldata.h Fri May 26 07:26:42 2006
--- curl_liblimitrate/lib/urldata.h Thu Jun 15 21:11:35 2006
***************
*** 1039,1044 ****
--- 1039,1046 ----
    curl_off_t infilesize; /* size of file to upload, -1 means unknown */
    long low_speed_limit; /* bytes/second */
    long low_speed_time; /* number of seconds */
+ long max_send_per_second; /* high speed limit in bytes/second for upload */
+ long max_recv_per_second; /* high speed limit in bytes/second for download */
    curl_off_t set_resume_from; /* continue [ftp] transfer from here */
    char *cookie; /* HTTP cookie string to send */
    struct curl_slist *headers; /* linked list of extra headers */
diff -cr --exclude CVS --exclude autom4te.cache curl/src/main.c curl_liblimitrate/src/main.c
*** curl/src/main.c Thu Jun 8 02:12:31 2006
--- curl_liblimitrate/src/main.c Thu Jun 15 21:12:22 2006
***************
*** 3941,3946 ****
--- 3941,3952 ----
          curl_easy_setopt(curl, CURLOPT_FTPPORT, config->ftpport);
          curl_easy_setopt(curl, CURLOPT_LOW_SPEED_LIMIT, config->low_speed_limit);
          curl_easy_setopt(curl, CURLOPT_LOW_SPEED_TIME, config->low_speed_time);
+ curl_easy_setopt(curl, CURLOPT_MAX_SEND_PER_SECOND, config->sendpersecond);
+ curl_easy_setopt(curl, CURLOPT_MAX_RECV_PER_SECOND, config->recvpersecond);
+ /* -- FIXME Disable main body rate throttling */
+ config->sendpersecond=0;
+ config->recvpersecond=0;
+ /* */
          curl_easy_setopt(curl, CURLOPT_RESUME_FROM_LARGE,
                           config->use_resume?config->resume_from:0);
          curl_easy_setopt(curl, CURLOPT_COOKIE, config->cookie);
Received on 2006-06-16