cURL / Mailing Lists / curl-library / Single Mail

curl-library

RE: CURL loops infinitely when cable is pulled out.

From: Sonia Subramanian <sonia_subramanian_at_symantec.com>
Date: Fri, 20 Apr 2007 18:08:01 -0700

Hi,

For issue 2, we would as far as possible like to avoid using timeout
values.
Please do let me know if a fix can be made so that this does not have to
be done. In Curl_readWrite the code path is as follows:
1.
if((k->keepon & (KEEP_READ|KEEP_READ_HOLD)) == KEEP_READ)
    fd_read = conn->sockfd;

2. fd_write = CURL_SOCKET_BAD;
3. select_res = Curl_socket_ready(fd_read, fd_write, 0);
  if(select_res == CSELECT_ERR) {
    failf(data, "select/poll returned error");
    return CURLE_SEND_ERROR;
  }
select res is 0.
4. if((k->keepon & KEEP_READ) &&
       ((select_res & CSELECT_IN) || conn->bits.stream_was_rewound)) { -
not satisfied
5. if((k->keepon & KEEP_WRITE) && (select_res & CSELECT_OUT)) { - not
satisfied
6. k->now = Curl_tvnow();
  if(didwhat) {
    /* Update read/write counters */
    if(k->bytecountp)
      *k->bytecountp = k->bytecount; /* read count */
    if(k->writebytecountp)
      *k->writebytecountp = k->writebytecount; /* write count */
  }
Didwhat is 0
7. result = Curl_speedcheck(data, k->now);
8. if(!k->keepon) { - not satisfied
9. *done = (bool)(0 == (k->keepon&(KEEP_READ|KEEP_WRITE))); done = 0.
10. return CURLE_OK

I guess my question is "Is a select value of 0 possible under normal
operation or would that always indicate a bad socket. Would it be safe
to treat select_res = 0 as a socket error and break out of the loop?" I
am not sure I want to put code like that in that would likely break
valid scenarios without verifying the same first. Or if didwhat and
select_res are both 0 can we set done to true. Otherwise we will keep
looping in this scenario.

I am using version 7.16.2.

Thanks,
Sonia.

-----Original Message-----
From: Sonia Subramanian
Sent: Friday, April 20, 2007 5:53 PM
To: 'libcurl development'
Cc: Charlotte Chang; Robert Spath; Shalu Jain
Subject: RE: CURL loops infinitely when cable is pulled out.

Hi,

I tried this out with the new code and there are 2 issues I thought I
would bring up:

One issue with partial download that I fixed:
1)
This was when I tried to resume download of an already partially
downloaded file.

In the function createconnection in url.c

I had to add the following lines:

else {
       /*
        * This is a brand new connection, so let's store it in the
connection
        * cache of ours!
        */
-> //Fix ssubrama - we have probably called Curl Disconnect
-> //Reset the entire resume from structure - to be safe.

-> data->reqdata.resume_from = data->set.set_resume_from;
-> if (data->reqdata.resume_from) {
-> if (data->reqdata.rangestringalloc == TRUE)
-> free(data->reqdata.range);
-> data->reqdata.range = aprintf("%" FORMAT_OFF_T
"-",
-> data->reqdata.resume_from);
-> if(!data->reqdata.range)
-> return CURLE_OUT_OF_MEMORY;
->
-> /* tell ourselves to fetch this range */
-> data->reqdata.use_range = TRUE; /* enable
range download */
-> data->reqdata.rangestringalloc = TRUE; /* mark
range string allocated */
-> }
-> else if (data->set.set_range) {
-> /* There is a range, but is not a resume, useful
for random ftp access */
-> data->reqdata.range = strdup(data->set.set_range);
-> if(!data->reqdata.range)
-> return CURLE_OUT_OF_MEMORY;
-> data->reqdata.rangestringalloc = TRUE; /* mark
range string allocated */
-> data->reqdata.use_range = TRUE; /* enable
range download */
-> }
-> else
-> data->reqdata.use_range = FALSE; /* disable
range download */
-> ConnectionStore(data, conn);
     }
   
     /* Continue connectdata initialization here. */
   

Because in
    reuse = ConnectionExists(data, conn, &conn_temp); if we call
Curl_disconnect - the partial - resume from information always gets
freed and is never reinitialized. So here I am checking if allocated I
am freeing it and then copying again. After this fix it worked.

The other issue is that the infinite loop does not go away.
If select returns 0 Curl_readwrite is called again and no condition
there terminates the loop.
(transfer.c
Function

static CURLcode
Transfer(struct connectdata *conn)
{
.
.
.

switch (Curl_socket_ready(fd_read, fd_write, 1000)) {
    case -1: /* select() error, stop reading */
#ifdef EINTR
      /* The EINTR is not serious, and it seems you might get this more
         ofen when using the lib in a multi-threaded environment! */
      if(SOCKERRNO == EINTR)
        ;
      else
#endif
        done = TRUE; /* no more read or write */
      continue;
    case 0: /* timeout */
    default: /* readable descriptors */

      result = Curl_readwrite(conn, &done);
      break;
    }
    if(result)
      return result;

    /* "done" signals to us if the transfer(s) are ready */
  }

  return CURLE_OK;
}

I am not sure about other implications and don't want to change anything
without your input.
I would appreciate your comments on the same. Also if you think that the
code is behaving as it should but the problem lies in the return values,
I would appreciate your letting us know,

Thanks,
Sonia.

-----Original Message-----
From: Sonia Subramanian
Sent: Thursday, April 19, 2007 8:47 PM
To: 'libcurl development'
Cc: Charlotte Chang; Robert Spath; Shalu Jain
Subject: RE: CURL loops infinitely when cable is pulled out.

Hi,

Thanks. I will try this out with the new code.

Thanks,
Sonia.

-----Original Message-----
From: curl-library-bounces_at_cool.haxx.se
[mailto:curl-library-bounces_at_cool.haxx.se] On Behalf Of Daniel Stenberg
Sent: Thursday, April 19, 2007 1:08 PM
To: libcurl development
Cc: Charlotte Chang; Robert Spath; Shalu Jain
Subject: RE: CURL loops infinitely when cable is pulled out.

On Thu, 19 Apr 2007, Sonia Subramanian wrote:

> 1. We don't have poll() and we probably will use select.
> 2. On this platform select returns 0 as I verified with 7.15.4

You mean when select() times out? That's pretty normal.

> 3. In the code that calls it Curl_readwrite is a value of select_res
==0
> handled?

Yes of course. timeouts are very frequent on all platforms for slow or
stalled
transfers.

> Is a select_res value of 0 valid?

Yes, it means the socket didn't turn readable within the given time
(assuming
we talk about downloads).

-- 
  Commercial curl and libcurl Technical Support:
http://haxx.se/curl.html
Received on 2007-04-21