Bogdan Nicula's second test case (posted Sun, 08 Oct 2006) converted to test
authorDaniel Stenberg <daniel@haxx.se>
Mon, 9 Oct 2006 06:58:05 +0000 (06:58 +0000)
committerDaniel Stenberg <daniel@haxx.se>
Mon, 9 Oct 2006 06:58:05 +0000 (06:58 +0000)
case 535 and it now runs fine. Again a problem with the pipelining code not
taking all possible (error) conditions into account.

CHANGES
lib/multi.c
lib/url.c
lib/url.h
tests/data/Makefile.am
tests/data/test535 [new file with mode: 0644]
tests/libtest/lib533.c

diff --git a/CHANGES b/CHANGES
index f567d42..f572e7e 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -6,9 +6,14 @@
 
                                   Changelog
 
+Daniel (9 October 2006)
+- Bogdan Nicula's second test case (posted Sun, 08 Oct 2006) converted to test
+  case 535 and it now runs fine. Again a problem with the pipelining code not
+  taking all possible (error) conditions into account.
+
 Daniel (6 October 2006)
-- Bogdan Nicula's hanging test case was converted to test case 533 and the test
-  now runs fine.
+- Bogdan Nicula's hanging test case (posted Wed, 04 Oct 2006) was converted to
+  test case 533 and the test now runs fine.
 
 Daniel (4 October 2006)
 - Dmitriy Sergeyev provided an example source code that crashed CVS libcurl
index ad6bebc..48863c8 100644 (file)
@@ -1081,9 +1081,14 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
       break;
 
     case CURLM_STATE_WAITPERFORM:
-      infof(easy->easy_handle, "Connection #%d: recv pipe size = %d\n",
+#ifdef CURLDEBUG
+      infof(easy->easy_handle, "Conn %d recv pipe %d inuse %d athead %d\n",
             easy->easy_conn->connectindex,
-            easy->easy_conn->recv_pipe->size);
+            easy->easy_conn->recv_pipe->size,
+            easy->easy_conn->readchannel_inuse,
+            Curl_isHandleAtHead(easy->easy_handle,
+                                easy->easy_conn->recv_pipe));
+#endif
       /* Wait for our turn to PERFORM */
       if (!easy->easy_conn->readchannel_inuse &&
           Curl_isHandleAtHead(easy->easy_handle,
index 7bcb982..3e2e371 100644 (file)
--- a/lib/url.c
+++ b/lib/url.c
@@ -1840,7 +1840,7 @@ void Curl_addHandleToPipeline(struct SessionHandle *data,
 }
 
 
-void Curl_removeHandleFromPipeline(struct SessionHandle *handle,
+int Curl_removeHandleFromPipeline(struct SessionHandle *handle,
                                    struct curl_llist *pipe)
 {
   struct curl_llist_element *curr;
@@ -1849,10 +1849,11 @@ void Curl_removeHandleFromPipeline(struct SessionHandle *handle,
   while (curr) {
     if (curr->ptr == handle) {
       Curl_llist_remove(pipe, curr, NULL);
-      break;
+      return 1; /* we removed a handle */
     }
     curr = curr->next;
   }
+  return 0;
 }
 
 #if 0
@@ -3975,8 +3976,14 @@ CURLcode Curl_done(struct connectdata **connp,
 
   conn->bits.done = TRUE; /* called just now! */
 
-  /* cleanups done even if the connection is re-used */
+  if(Curl_removeHandleFromPipeline(data, conn->recv_pipe) &&
+     conn->readchannel_inuse)
+    conn->readchannel_inuse--;
+  if(Curl_removeHandleFromPipeline(data, conn->send_pipe) &&
+     conn->writechannel_inuse)
+    conn->writechannel_inuse--;
 
+  /* cleanups done even if the connection is re-used */
   if(data->reqdata.rangestringalloc) {
     free(data->reqdata.range);
     data->reqdata.rangestringalloc = FALSE;
index e1754c3..83706fd 100644 (file)
--- a/lib/url.h
+++ b/lib/url.h
@@ -64,8 +64,8 @@ int Curl_doing_getsock(struct connectdata *conn,
 
 void Curl_addHandleToPipeline(struct SessionHandle *handle,
                               struct curl_llist *pipe);
-void Curl_removeHandleFromPipeline(struct SessionHandle *handle,
-                                   struct curl_llist *pipe);
+int Curl_removeHandleFromPipeline(struct SessionHandle *handle,
+                                  struct curl_llist *pipe);
 bool Curl_isHandleAtHead(struct SessionHandle *handle,
                          struct curl_llist *pipe);
 
index 1fd5b7f..ffb392f 100644 (file)
@@ -36,4 +36,4 @@ EXTRA_DIST = test1 test108 test117 test127 test20 test27 test34 test46           \
  test265 test266 test267 test268 test269 test270 test271 test272 test273   \
  test274 test275 test524 test525 test276 test277 test526 test527 test528   \
  test530 DISABLED test278 test279 test531 test280 test529 test532 test533  \
- test534
+ test534 test535
diff --git a/tests/data/test535 b/tests/data/test535
new file mode 100644 (file)
index 0000000..ea43a1a
--- /dev/null
@@ -0,0 +1,59 @@
+<reply>
+<data mode="text">
+HTTP/1.1 404 Badness
+Date: Thu, 09 Nov 2010 14:49:00 GMT
+ETag: "21025-dc7-39462498"
+Content-Length: 6
+Content-Type: text/html
+Funny-head: yesyes
+
+hejsan
+</data>
+<data1>
+HTTP/1.1 200 Fine
+Date: Thu, 09 Nov 2010 14:49:00 GMT
+Content-Length: 13
+Connection: close
+Content-Type: text/html
+
+fine content
+</data1>
+
+<datacheck>
+fine content
+</datacheck>
+
+</reply>
+
+# Client-side
+<client>
+<server>
+http
+</server>
+# tool is what to use instead of 'curl'
+<tool>
+lib533
+</tool>
+
+ <name>
+HTTP GET multi two files with FAILONERROR
+ </name>
+ <command>
+http://%HOSTIP:%HTTPPORT/535 http://%HOSTIP:%HTTPPORT/5350001
+</command>
+</client>
+
+#
+# Verify data after the test has been "shot"
+<verify>
+<protocol>
+GET /535 HTTP/1.1\r
+Host: 127.0.0.1:%HTTPPORT\r
+Accept: */*\r
+\r
+GET /5350001 HTTP/1.1\r
+Host: 127.0.0.1:%HTTPPORT\r
+Accept: */*\r
+\r
+</protocol>
+</verify>
index afbb7bd..3a1e7df 100644 (file)
@@ -34,9 +34,8 @@ int test(char *URL)
     return 100 + i; /* major bad */
 
   curl_easy_setopt(curl, CURLOPT_URL, URL);
-
-  /* go verbose */
   curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);
+  curl_easy_setopt(curl, CURLOPT_FAILONERROR, 1);
 
   m = curl_multi_init();
 
@@ -65,6 +64,7 @@ int test(char *URL)
           curl_easy_reset(curl);
           curl_easy_setopt(curl, CURLOPT_URL, arg2);
           curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);
+          curl_easy_setopt(curl, CURLOPT_FAILONERROR, 1);
 
           /* re-add it */
           res = (int)curl_multi_add_handle(m, curl);