(http://curl.haxx.se/bug/view.cgi?id=2351645) that identified a problem with
  the multi interface that occured if you removed an easy handle while in
  progress and the handle was used in a HTTP pipeline.
This commit is contained in:
Daniel Stenberg 2008-12-03 15:20:27 +00:00
Родитель 4ee27b4594
Коммит 479ddb1fee
5 изменённых файлов: 45 добавлений и 22 удалений

Просмотреть файл

@ -6,7 +6,12 @@
Changelog Changelog
Daniel Fandrich (3 Dec 2008) Daniel Stenberg (3 Dec 2008)
- Igor Novoseltsev filed bug #2351645
(http://curl.haxx.se/bug/view.cgi?id=2351645) that identified a problem with
the multi interface that occured if you removed an easy handle while in
progress and the handle was used in a HTTP pipeline.
- Pawel Kierski pointed out a mistake in the cookie code that could lead to a - Pawel Kierski pointed out a mistake in the cookie code that could lead to a
bad fclose() after a fatal error had occured. bad fclose() after a fatal error had occured.
(http://curl.haxx.se/bug/view.cgi?id=2382219) (http://curl.haxx.se/bug/view.cgi?id=2382219)

Просмотреть файл

@ -23,6 +23,7 @@ This release includes the following bugfixes:
o removed the default use of "Pragma: no-cache" o removed the default use of "Pragma: no-cache"
o fix SCP/SFTP busyloop by using a new libssh2 0.19 function o fix SCP/SFTP busyloop by using a new libssh2 0.19 function
o bad fclose() after a fatal error in cookie code o bad fclose() after a fatal error in cookie code
o curl_multi_remove_handle() when the handle was in use in a HTTP pipeline
This release includes the following known bugs: This release includes the following known bugs:
@ -32,6 +33,6 @@ This release would not have looked like this without help, code, reports and
advice from friends like these: advice from friends like these:
Yang Tse, Daniel Fandrich, Jim Meyering, Christian Krause, Andreas Wurf, Yang Tse, Daniel Fandrich, Jim Meyering, Christian Krause, Andreas Wurf,
Markus Koetter, Josef Wolf, Vlad Grachov, Pawel Kierski Markus Koetter, Josef Wolf, Vlad Grachov, Pawel Kierski, Igor Novoseltsev
Thanks! (and sorry if I forgot to mention someone) Thanks! (and sorry if I forgot to mention someone)

Просмотреть файл

@ -620,22 +620,27 @@ CURLMcode curl_multi_remove_handle(CURLM *multi_handle,
easy->easy_handle->dns.hostcachetype = HCACHE_NONE; easy->easy_handle->dns.hostcachetype = HCACHE_NONE;
} }
/* we must call Curl_done() here (if we still "own it") so that we don't if(easy->easy_conn) {
leave a half-baked one around */
if(easy->easy_conn &&
(easy->easy_conn->data == easy->easy_handle)) {
/* Curl_done() clears the conn->data field to lose the association /* we must call Curl_done() here (if we still "own it") so that we don't
between the easy handle and the connection leave a half-baked one around */
if (easy->easy_conn->data == easy->easy_handle) {
Note that this ignores the return code simply because there's nothing /* Curl_done() clears the conn->data field to lose the association
really useful to do with it anyway! */ between the easy handle and the connection
(void)Curl_done(&easy->easy_conn, easy->result, premature);
if(easy->easy_conn) Note that this ignores the return code simply because there's
/* the connection is still alive, set back the association to enable nothing really useful to do with it anyway! */
the check below to trigger TRUE */ (void)Curl_done(&easy->easy_conn, easy->result, premature);
easy->easy_conn->data = easy->easy_handle;
if(easy->easy_conn)
/* the connection is still alive, set back the association to enable
the check below to trigger TRUE */
easy->easy_conn->data = easy->easy_handle;
}
else
/* Clear connection pipelines, if Curl_done above was not called */
Curl_getoff_all_pipelines(easy->easy_handle, easy->easy_conn);
} }
/* If this easy_handle was the last one in charge for one or more /* If this easy_handle was the last one in charge for one or more

Просмотреть файл

@ -2359,6 +2359,20 @@ int Curl_removeHandleFromPipeline(struct SessionHandle *handle,
return 0; return 0;
} }
/* remove the specified connection from all (possible) pipelines and related
queues */
void Curl_getoff_all_pipelines(struct SessionHandle *data,
struct connectdata *conn)
{
if(Curl_removeHandleFromPipeline(data, conn->recv_pipe) &&
conn->readchannel_inuse)
conn->readchannel_inuse = FALSE;
if(Curl_removeHandleFromPipeline(data, conn->send_pipe) &&
conn->writechannel_inuse)
conn->writechannel_inuse = FALSE;
Curl_removeHandleFromPipeline(data, conn->pend_pipe);
}
#if 0 /* this code is saved here as it is useful for debugging purposes */ #if 0 /* this code is saved here as it is useful for debugging purposes */
static void Curl_printPipeline(struct curl_llist *pipeline) static void Curl_printPipeline(struct curl_llist *pipeline)
{ {
@ -4548,13 +4562,7 @@ CURLcode Curl_done(struct connectdata **connp,
Curl_expire(data, 0); /* stop timer */ Curl_expire(data, 0); /* stop timer */
if(Curl_removeHandleFromPipeline(data, conn->recv_pipe) && Curl_getoff_all_pipelines(data, conn);
conn->readchannel_inuse)
conn->readchannel_inuse = FALSE;
if(Curl_removeHandleFromPipeline(data, conn->send_pipe) &&
conn->writechannel_inuse)
conn->writechannel_inuse = FALSE;
Curl_removeHandleFromPipeline(data, conn->pend_pipe);
if(conn->bits.done || if(conn->bits.done ||
(conn->send_pipe->size + conn->recv_pipe->size != 0 && (conn->send_pipe->size + conn->recv_pipe->size != 0 &&

Просмотреть файл

@ -69,6 +69,10 @@ CURLcode Curl_addHandleToPipeline(struct SessionHandle *handle,
struct curl_llist *pipeline); struct curl_llist *pipeline);
int Curl_removeHandleFromPipeline(struct SessionHandle *handle, int Curl_removeHandleFromPipeline(struct SessionHandle *handle,
struct curl_llist *pipeline); struct curl_llist *pipeline);
/* remove the specified connection from all (possible) pipelines and related
queues */
void Curl_getoff_all_pipelines(struct SessionHandle *data,
struct connectdata *conn);
void Curl_close_connections(struct SessionHandle *data); void Curl_close_connections(struct SessionHandle *data);