curl-library
RE: CURL loops infinitely when cable is pulled out.
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.htmlReceived on 2007-04-21