Commit 479ddb1f authored by Daniel Stenberg's avatar Daniel Stenberg
Browse files

- 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.
parent 4ee27b45
Loading
Loading
Loading
Loading
+6 −1
Original line number Diff line number Diff line
@@ -6,7 +6,12 @@

                                  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
  bad fclose() after a fatal error had occured.
  (http://curl.haxx.se/bug/view.cgi?id=2382219)
+2 −1
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@ This release includes the following bugfixes:
 o removed the default use of "Pragma: no-cache"
 o fix SCP/SFTP busyloop by using a new libssh2 0.19 function
 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:

@@ -32,6 +33,6 @@ This release would not have looked like this without help, code, reports and
advice from friends like these:

 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)
+18 −13
Original line number Diff line number Diff line
@@ -620,16 +620,17 @@ CURLMcode curl_multi_remove_handle(CURLM *multi_handle,
      easy->easy_handle->dns.hostcachetype = HCACHE_NONE;
    }

    if(easy->easy_conn) {

      /* we must call Curl_done() here (if we still "own it") so that we don't
         leave a half-baked one around */
    if(easy->easy_conn &&
       (easy->easy_conn->data == easy->easy_handle)) {
      if (easy->easy_conn->data == easy->easy_handle) {

        /* Curl_done() clears the conn->data field to lose the association
           between the easy handle and the connection

         Note that this ignores the return code simply because there's nothing
         really useful to do with it anyway! */
           Note that this ignores the return code simply because there's
           nothing really useful to do with it anyway! */
        (void)Curl_done(&easy->easy_conn, easy->result, premature);

        if(easy->easy_conn)
@@ -637,6 +638,10 @@ CURLMcode curl_multi_remove_handle(CURLM *multi_handle,
             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
       connections a the shared connection cache, we might need to keep this
+15 −7
Original line number Diff line number Diff line
@@ -2359,6 +2359,20 @@ int Curl_removeHandleFromPipeline(struct SessionHandle *handle,
  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 */
static void Curl_printPipeline(struct curl_llist *pipeline)
{
@@ -4548,13 +4562,7 @@ CURLcode Curl_done(struct connectdata **connp,

  Curl_expire(data, 0); /* stop timer */

  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);
  Curl_getoff_all_pipelines(data, conn);

  if(conn->bits.done ||
     (conn->send_pipe->size + conn->recv_pipe->size != 0 &&
+4 −0
Original line number Diff line number Diff line
@@ -69,6 +69,10 @@ CURLcode Curl_addHandleToPipeline(struct SessionHandle *handle,
                                  struct curl_llist *pipeline);
int Curl_removeHandleFromPipeline(struct SessionHandle *handle,
                                  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);