summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Stenberg <daniel@haxx.se>2002-04-27 22:21:51 +0000
committerDaniel Stenberg <daniel@haxx.se>2002-04-27 22:21:51 +0000
commit969a25d1b20520e7141c9655d24ff07752856907 (patch)
tree28d2dd8b356614aa03df99e7bb7db72f7f310ce9
parentf144f77ba7dc0bd4f99d955726c898a19b455e41 (diff)
downloadgnurl-969a25d1b20520e7141c9655d24ff07752856907.tar.gz
gnurl-969a25d1b20520e7141c9655d24ff07752856907.tar.bz2
gnurl-969a25d1b20520e7141c9655d24ff07752856907.zip
implemented curl_multi_info_read() which I had forgotten before!
-rw-r--r--lib/multi.c99
1 files changed, 90 insertions, 9 deletions
diff --git a/lib/multi.c b/lib/multi.c
index 449469c88..a21fc5674 100644
--- a/lib/multi.c
+++ b/lib/multi.c
@@ -30,6 +30,11 @@
#include "transfer.h"
#include "url.h"
+/* The last #include file should be: */
+#ifdef MALLOCDEBUG
+#include "memdebug.h"
+#endif
+
struct Curl_message {
/* the 'CURLMsg' is the part that is visible to the external user */
struct CURLMsg extmsg;
@@ -77,9 +82,14 @@ struct Curl_multi {
int num_easy;
/* this is a linked list of posted messages */
- struct Curl_message *msgs;
- /* amount of messages in the queue */
- int num_msgs;
+ struct Curl_message *msgs; /* the messages remain here until the handle is
+ closed */
+ struct Curl_message *lastmsg; /* points to the last entry */
+ struct Curl_message *readptr; /* NULL before no one read anything */
+
+ int num_msgs; /* amount of messages in the queue */
+ int num_read; /* amount of read messages */
+
/* Hostname cache */
curl_hash *hostcache;
};
@@ -259,7 +269,7 @@ CURLMcode curl_multi_perform(CURLM *multi_handle, int *running_handles)
}
else {
if (multi->hostcache == NULL) {
- multi->hostcache = curl_hash_alloc(7, Curl_freeaddrinfo);
+ multi->hostcache = Curl_hash_alloc(7, Curl_freeaddrinfo);
}
easy->easy_handle->hostcache = multi->hostcache;
@@ -301,9 +311,34 @@ CURLMcode curl_multi_perform(CURLM *multi_handle, int *running_handles)
case CURLM_STATE_DONE:
/* post-transfer command */
easy->result = Curl_done(easy->easy_conn);
- /* after we have DONE what we're supposed to do, go COMPLETED */
- if(CURLE_OK == easy->result)
- easy->state = CURLM_STATE_COMPLETED;
+
+ /* after we have DONE what we're supposed to do, go COMPLETED, and
+ it doesn't matter what the Curl_done() returned! */
+ easy->state = CURLM_STATE_COMPLETED;
+
+ /* clear out the usage of the shared DNS cache */
+ easy->easy_handle->hostcache = NULL;
+
+ /* now add a node to the Curl_message linked list with this info */
+ {
+ struct Curl_message *msg = (struct Curl_message *)
+ malloc(sizeof(struct Curl_message));
+ msg->extmsg.msg = CURLMSG_DONE;
+ msg->extmsg.easy_handle = easy->easy_handle;
+ msg->extmsg.data.result = easy->result;
+ msg->next=NULL;
+
+ if(multi->lastmsg) {
+ multi->lastmsg->next = msg;
+ multi->lastmsg = msg;
+ }
+ else {
+ multi->msgs = msg;
+ multi->lastmsg = msg;
+ }
+ multi->num_msgs++; /* increase message counter */
+
+ }
break;
case CURLM_STATE_COMPLETED:
/* this is a completed transfer, it is likely to still be connected */
@@ -335,10 +370,30 @@ CURLMcode curl_multi_perform(CURLM *multi_handle, int *running_handles)
CURLMcode curl_multi_cleanup(CURLM *multi_handle)
{
struct Curl_multi *multi=(struct Curl_multi *)multi_handle;
+ struct Curl_one_easy *easy;
+ struct Curl_one_easy *nexteasy;
+ struct Curl_message *msg;
+ struct Curl_message *nextmsg;
+
if(GOOD_MULTI_HANDLE(multi)) {
multi->type = 0; /* not good anymore */
- curl_hash_destroy(multi->hostcache);
+ Curl_hash_destroy(multi->hostcache);
+
/* remove all easy handles */
+ easy = multi->easy.next;
+ while(easy) {
+ nexteasy=easy->next;
+ free(easy);
+ easy = nexteasy;
+ }
+
+ /* remove all struct Curl_message nodes left */
+ msg = multi->msgs;
+ while(msg) {
+ nextmsg = msg->next;
+ free(msg);
+ msg = nextmsg;
+ }
free(multi);
@@ -348,7 +403,33 @@ CURLMcode curl_multi_cleanup(CURLM *multi_handle)
return CURLM_BAD_HANDLE;
}
-CURLMsg *curl_multi_info_read(CURLM *multi_handle, int *msgs_in_queue);
+CURLMsg *curl_multi_info_read(CURLM *multi_handle, int *msgs_in_queue)
+{
+ struct Curl_multi *multi=(struct Curl_multi *)multi_handle;
+ if(GOOD_MULTI_HANDLE(multi)) {
+ CURLMsg *msg;
+
+ if(!multi->readptr && !multi->num_read)
+ multi->readptr = multi->msgs;
+
+ if(!multi->readptr) {
+ *msgs_in_queue = 0;
+ return NULL;
+ }
+
+ multi->num_read++;
+
+ *msgs_in_queue = multi->num_msgs - multi->num_read;
+ msg = &multi->readptr->extmsg;
+
+ /* advance read pointer */
+ multi->readptr = multi->readptr->next;
+
+ return msg;
+ }
+ else
+ return CURLM_BAD_HANDLE;
+}
/*
* local variables: