gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[GNUnet-SVN] [gnurl] 126/254: multi: use a fixed array of timers instead


From: gnunet
Subject: [GNUnet-SVN] [gnurl] 126/254: multi: use a fixed array of timers instead of malloc
Date: Sat, 17 Jun 2017 16:52:38 +0200

This is an automated email from the git hooks/post-receive script.

ng0 pushed a commit to annotated tag gnurl-7.54.1
in repository gnurl.

commit 31b39c40cf909d34f27dc655755f346482f57089
Author: Daniel Stenberg <address@hidden>
AuthorDate: Tue May 9 12:47:49 2017 +0200

    multi: use a fixed array of timers instead of malloc
    
    ... since the total amount is low this is faster, easier and reduces
    memory overhead.
    
    Also, Curl_expire_done() can now mark an expire timeout as done so that
    it never times out.
    
    Closes #1472
---
 lib/asyn-ares.c   |  2 +-
 lib/asyn-thread.c |  4 ++--
 lib/easy.c        |  2 +-
 lib/http.c        |  3 +++
 lib/http2.c       |  8 +++----
 lib/llist.c       |  3 ++-
 lib/multi.c       | 62 +++++++++++++++++++++----------------------------------
 lib/multiif.h     | 20 +-----------------
 lib/pipeline.c    |  4 ++--
 lib/ssh.c         |  2 +-
 lib/transfer.c    |  1 +
 lib/urldata.h     | 25 ++++++++++++++++++++++
 12 files changed, 66 insertions(+), 70 deletions(-)

diff --git a/lib/asyn-ares.c b/lib/asyn-ares.c
index a8396ea52..12f35e412 100644
--- a/lib/asyn-ares.c
+++ b/lib/asyn-ares.c
@@ -232,7 +232,7 @@ int Curl_resolver_getsock(struct connectdata *conn,
   milli = (timeout->tv_sec * 1000) + (timeout->tv_usec/1000);
   if(milli == 0)
     milli += 10;
-  Curl_expire_latest(conn->data, milli, EXPIRE_ARES);
+  Curl_expire_latest(conn->data, milli, EXPIRE_ASYNC_NAME);
 
   return max;
 }
diff --git a/lib/asyn-thread.c b/lib/asyn-thread.c
index 2138c78b8..65fa6c5be 100644
--- a/lib/asyn-thread.c
+++ b/lib/asyn-thread.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2016, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <address@hidden>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -540,7 +540,7 @@ CURLcode Curl_resolver_is_resolved(struct connectdata *conn,
       td->poll_interval = 250;
 
     td->interval_end = elapsed + td->poll_interval;
-    Curl_expire(conn->data, td->poll_interval);
+    Curl_expire(conn->data, td->poll_interval, EXPIRE_ASYNC_NAME);
   }
 
   return CURLE_OK;
diff --git a/lib/easy.c b/lib/easy.c
index d4add46cc..46c0a9911 100644
--- a/lib/easy.c
+++ b/lib/easy.c
@@ -1044,7 +1044,7 @@ CURLcode curl_easy_pause(struct Curl_easy *data, int 
action)
   if(!result &&
      ((newstate&(KEEP_RECV_PAUSE|KEEP_SEND_PAUSE)) !=
       (KEEP_RECV_PAUSE|KEEP_SEND_PAUSE)) )
-    Curl_expire(data, 0, EXPIRE_UNPAUSE); /* get this handle going again */
+    Curl_expire(data, 0, EXPIRE_RUN_NOW); /* get this handle going again */
 
   return result;
 }
diff --git a/lib/http.c b/lib/http.c
index 93aac201c..8e7fb0fa9 100644
--- a/lib/http.c
+++ b/lib/http.c
@@ -2746,6 +2746,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
       data->req.upload_done = TRUE;
       data->req.keepon &= ~KEEP_SEND; /* we're done writing */
       data->req.exp100 = EXP100_SEND_DATA; /* already sent */
+      Curl_expire_done(data, EXPIRE_100_TIMEOUT);
     }
   }
 
@@ -3042,6 +3043,7 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy 
*data,
           if(k->exp100 > EXP100_SEND_DATA) {
             k->exp100 = EXP100_SEND_DATA;
             k->keepon |= KEEP_SEND;
+            Curl_expire_done(data, EXPIRE_100_TIMEOUT);
           }
           break;
         case 101:
@@ -3168,6 +3170,7 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy 
*data,
              * request body has been sent we stop sending and mark the
              * connection for closure after we've read the entire response.
              */
+            Curl_expire_done(data, EXPIRE_100_TIMEOUT);
             if(!k->upload_done) {
               if(data->set.http_keep_sending_on_error) {
                 infof(data, "HTTP error before end of send, keep sending\n");
diff --git a/lib/http2.c b/lib/http2.c
index 994e53deb..c65305029 100644
--- a/lib/http2.c
+++ b/lib/http2.c
@@ -569,7 +569,7 @@ static int on_frame_recv(nghttp2_session *session, const 
nghttp2_frame *frame,
 
       /* if we receive data for another handle, wake that up */
       if(conn_s->data != data_s)
-        Curl_expire(data_s, 0, EXPIRE_H2DATA);
+        Curl_expire(data_s, 0, EXPIRE_RUN_NOW);
     }
     break;
   case NGHTTP2_PUSH_PROMISE:
@@ -646,7 +646,7 @@ static int on_data_chunk_recv(nghttp2_session *session, 
uint8_t flags,
 
   /* if we receive data for another handle, wake that up */
   if(conn->data != data_s)
-    Curl_expire(data_s, 0, EXPIRE_H2DATA);
+    Curl_expire(data_s, 0, EXPIRE_RUN_NOW);
 
   DEBUGF(infof(data_s, "%zu data received for stream %u "
                "(%zu left in buffer %p, total %zu)\n",
@@ -909,7 +909,7 @@ static int on_header(nghttp2_session *session, const 
nghttp2_frame *frame,
     Curl_add_buffer(stream->header_recvbuf, " \r\n", 3);
     /* if we receive data for another handle, wake that up */
     if(conn->data != data_s)
-      Curl_expire(data_s, 0, EXPIRE_H2DATA);
+      Curl_expire(data_s, 0, EXPIRE_RUN_NOW);
 
     DEBUGF(infof(data_s, "h2 status: HTTP/2 %03d (easy %p)\n",
                  stream->status_code, data_s));
@@ -925,7 +925,7 @@ static int on_header(nghttp2_session *session, const 
nghttp2_frame *frame,
   Curl_add_buffer(stream->header_recvbuf, "\r\n", 2);
   /* if we receive data for another handle, wake that up */
   if(conn->data != data_s)
-    Curl_expire(data_s, 0, EXPIRE_H2DATA);
+    Curl_expire(data_s, 0, EXPIRE_RUN_NOW);
 
   DEBUGF(infof(data_s, "h2 header: %.*s: %.*s\n", namelen, name, valuelen,
                value));
diff --git a/lib/llist.c b/lib/llist.c
index 06cebb971..4bb0a51b8 100644
--- a/lib/llist.c
+++ b/lib/llist.c
@@ -122,7 +122,8 @@ Curl_llist_remove(struct curl_llist *list, struct 
curl_llist_element *e,
   --list->size;
 
   /* call the dtor() last for when it actually frees the 'e' memory itself */
-  list->dtor(user, ptr);
+  if(list->dtor)
+    list->dtor(user, ptr);
 }
 
 void
diff --git a/lib/multi.c b/lib/multi.c
index cfcc8d6c5..252cd2ae4 100644
--- a/lib/multi.c
+++ b/lib/multi.c
@@ -99,8 +99,6 @@ static const char * const statename[]={
 };
 #endif
 
-static void multi_freetimeout(void *a, void *b);
-
 /* function pointer called once when switching TO a state */
 typedef void (*init_multistate_func)(struct Curl_easy *data);
 
@@ -369,7 +367,7 @@ CURLMcode curl_multi_add_handle(struct Curl_multi *multi,
     return CURLM_ADDED_ALREADY;
 
   /* Initialize timeout list for this handle */
-  Curl_llist_init(&data->state.timeoutlist, multi_freetimeout);
+  Curl_llist_init(&data->state.timeoutlist, NULL);
 
   /*
    * No failure allowed in this function beyond this point. And no
@@ -430,7 +428,7 @@ CURLMcode curl_multi_add_handle(struct Curl_multi *multi,
      sockets that time-out or have actions will be dealt with. Since this
      handle has no action yet, we make sure it times out to get things to
      happen. */
-  Curl_expire(data, 0, EXPIRE_ADD_HANDLE);
+  Curl_expire(data, 0, EXPIRE_RUN_NOW);
 
   /* increase the node-counter */
   multi->num_easy++;
@@ -1941,7 +1939,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
         /* expire the new receiving pipeline head */
         if(data->easy_conn->recv_pipe.head)
           Curl_expire_latest(data->easy_conn->recv_pipe.head->ptr, 0,
-                             EXPIRE_PIPELINE_READ);
+                             EXPIRE_RUN_NOW);
 
         /* Check if we can move pending requests to send pipe */
         Curl_multi_process_pending_handles(multi);
@@ -2482,12 +2480,6 @@ void Curl_multi_closed(struct connectdata *conn, 
curl_socket_t s)
   }
 }
 
-struct time_node {
-  struct curl_llist_element list;
-  struct timeval time;
-  expire_id id;
-};
-
 /*
  * add_next_timeout()
  *
@@ -2860,34 +2852,19 @@ static int update_timer(struct Curl_multi *multi)
 }
 
 /*
- * multi_freetimeout()
- *
- * Callback used by the llist system when a single timeout list entry is
- * destroyed.
- */
-static void multi_freetimeout(void *user, void *entryptr)
-{
-  (void)user;
-
-  /* the entry was plain malloc()'ed */
-  free(entryptr);
-}
-
-/*
  * multi_deltimeout()
  *
  * Remove a given timestamp from the list of timeouts.
  */
 static void
-multi_deltimeout(struct Curl_easy *data, expire_id id)
+multi_deltimeout(struct Curl_easy *data, expire_id eid)
 {
   struct curl_llist_element *e;
   struct curl_llist *timeoutlist = &data->state.timeoutlist;
-
-  /* find and remove the node(s) from the list */
+  /* find and remove the specific node from the list */
   for(e = timeoutlist->head; e; e = e->next) {
-    struct time_node *node = (struct time_node *)e->ptr;
-    if(node->id == id) {
+    struct time_node *n = (struct time_node *)e->ptr;
+    if(n->eid == eid) {
       Curl_llist_remove(timeoutlist, e, NULL);
       return;
     }
@@ -2904,7 +2881,7 @@ multi_deltimeout(struct Curl_easy *data, expire_id id)
 static CURLMcode
 multi_addtimeout(struct Curl_easy *data,
                  struct timeval *stamp,
-                 int id)
+                 expire_id eid)
 {
   struct curl_llist_element *e;
   struct time_node *node;
@@ -2912,13 +2889,11 @@ multi_addtimeout(struct Curl_easy *data,
   size_t n;
   struct curl_llist *timeoutlist = &data->state.timeoutlist;
 
-  node = malloc(sizeof(struct time_node));
-  if(!node)
-    return CURLM_OUT_OF_MEMORY;
+  node = &data->state.expires[eid];
 
   /* copy the timestamp and id */
   memcpy(&node->time, stamp, sizeof(*stamp));
-  node->id = id;
+  node->eid = eid; /* also marks it as in use */
 
   n = Curl_llist_count(timeoutlist);
   infof(data, "TIMEOUTS %zd\n", n);
@@ -2949,9 +2924,7 @@ multi_addtimeout(struct Curl_easy *data,
  * The timeout will be added to a queue of timeouts if it defines a moment in
  * time that is later than the current head of queue.
  *
- * If 'id' is given (non-zero), expire will replace a former timeout using the
- * same id. id is also a good way to keep track of the purpose of each
- * timeout.
+ * Expire replaces a former timeout using the same id if already set.
  */
 void Curl_expire(struct Curl_easy *data, time_t milli, expire_id id)
 {
@@ -3056,6 +3029,17 @@ void Curl_expire_latest(struct Curl_easy *data, time_t 
milli, expire_id id)
   Curl_expire(data, milli, id);
 }
 
+/*
+ * Curl_expire_done()
+ *
+ * Removes the expire timer. Marks it as done.
+ *
+ */
+void Curl_expire_done(struct Curl_easy *data, expire_id id)
+{
+  /* remove the timer, if there */
+  multi_deltimeout(data, id);
+}
 
 /*
  * Curl_expire_clear()
@@ -3160,7 +3144,7 @@ void Curl_multi_process_pending_handles(struct Curl_multi 
*multi)
       Curl_llist_remove(&multi->pending, e, NULL);
 
       /* Make sure that the handle will be processed soonish. */
-      Curl_expire_latest(data, 0, EXPIRE_MULTI_PENDING);
+      Curl_expire_latest(data, 0, EXPIRE_RUN_NOW);
     }
 
     e = next; /* operate on next handle */
diff --git a/lib/multiif.h b/lib/multiif.h
index a9a7a5577..a833e23e0 100644
--- a/lib/multiif.h
+++ b/lib/multiif.h
@@ -26,28 +26,10 @@
  * Prototypes for library-wide functions provided by multi.c
  */
 
-/* Timers */
-typedef enum {
-  EXPIRE_SPEEDCHECK,
-  EXPIRE_H2DATA,
-  EXPIRE_PIPELINE_SEND,
-  EXPIRE_PIPELINE_READ,
-  EXPIRE_ADD_HANDLE,
-  EXPIRE_TOOFAST,
-  EXPIRE_UNPAUSE,
-  EXPIRE_ARES,
-  EXPIRE_MULTI_PENDING,
-  EXPIRE_DNS_PER_NAME,
-  EXPIRE_HAPPY_EYEBALLS,
-  EXPIRE_100_TIMEOUT,
-  EXPIRE_TIMEOUT,
-  EXPIRE_CONNECTTIMEOUT,
-  EXPIRE_LAST /* not an actual timer, used as a marker only */
-} expire_id;
-
 void Curl_expire(struct Curl_easy *data, time_t milli, expire_id);
 void Curl_expire_clear(struct Curl_easy *data);
 void Curl_expire_latest(struct Curl_easy *data, time_t milli, expire_id);
+void Curl_expire_done(struct Curl_easy *data, expire_id id);
 bool Curl_pipeline_wanted(const struct Curl_multi* multi, int bits);
 void Curl_multi_handlePipeBreak(struct Curl_easy *data);
 
diff --git a/lib/pipeline.c b/lib/pipeline.c
index 729e69c27..b8d203745 100644
--- a/lib/pipeline.c
+++ b/lib/pipeline.c
@@ -113,7 +113,7 @@ CURLcode Curl_add_handle_to_pipeline(struct Curl_easy 
*handle,
   if(pipeline == &conn->send_pipe && sendhead != conn->send_pipe.head) {
     /* this is a new one as head, expire it */
     Curl_pipeline_leave_write(conn); /* not in use yet */
-    Curl_expire(conn->send_pipe.head->ptr, 0, EXPIRE_PIPELINE_SEND);
+    Curl_expire(conn->send_pipe.head->ptr, 0, EXPIRE_RUN_NOW);
   }
 
 #if 0 /* enable for pipeline debugging */
@@ -148,7 +148,7 @@ void Curl_move_handle_from_send_to_recv_pipe(struct 
Curl_easy *handle,
         infof(conn->data, "%p is at send pipe head B!\n",
               (void *)conn->send_pipe.head->ptr);
 #endif
-        Curl_expire(conn->send_pipe.head->ptr, 0, EXPIRE_PIPELINE_READ);
+        Curl_expire(conn->send_pipe.head->ptr, 0, EXPIRE_RUN_NOW);
       }
 
       /* The receiver's list is not really interesting here since either this
diff --git a/lib/ssh.c b/lib/ssh.c
index 50f1dcb4e..863d7fd54 100644
--- a/lib/ssh.c
+++ b/lib/ssh.c
@@ -1891,7 +1891,7 @@ static CURLcode ssh_statemach_act(struct connectdata 
*conn, bool *block)
         /* since we don't really wait for anything at this point, we want the
            state machine to move on as soon as possible so we set a very short
            timeout here */
-        Curl_expire(data, 0);
+        Curl_expire(data, 0, EXPIRE_RUN_NOW);
 
         state(conn, SSH_STOP);
       }
diff --git a/lib/transfer.c b/lib/transfer.c
index b7435f9ae..73497f79f 100644
--- a/lib/transfer.c
+++ b/lib/transfer.c
@@ -1139,6 +1139,7 @@ CURLcode Curl_readwrite(struct connectdata *conn,
         /* we've waited long enough, continue anyway */
         k->exp100 = EXP100_SEND_DATA;
         k->keepon |= KEEP_SEND;
+        Curl_expire_done(data, EXPIRE_100_TIMEOUT);
         infof(data, "Done waiting for 100-continue\n");
       }
     }
diff --git a/lib/urldata.h b/lib/urldata.h
index 84124b658..d4a4a98dc 100644
--- a/lib/urldata.h
+++ b/lib/urldata.h
@@ -1314,6 +1314,30 @@ struct tempbuf {
                  Curl_client_write() */
 };
 
+/* Timers */
+typedef enum {
+  EXPIRE_100_TIMEOUT,
+  EXPIRE_ASYNC_NAME,
+  EXPIRE_CONNECTTIMEOUT,
+  EXPIRE_DNS_PER_NAME,
+  EXPIRE_HAPPY_EYEBALLS,
+  EXPIRE_MULTI_PENDING,
+  EXPIRE_RUN_NOW,
+  EXPIRE_SPEEDCHECK,
+  EXPIRE_TIMEOUT,
+  EXPIRE_TOOFAST,
+  EXPIRE_LAST /* not an actual timer, used as a marker only */
+} expire_id;
+
+/*
+ * One instance for each timeout an easy handle can set.
+ */
+struct time_node {
+  struct curl_llist_element list;
+  struct timeval time;
+  expire_id eid;
+};
+
 struct UrlState {
 
   /* Points to the connection cache */
@@ -1382,6 +1406,7 @@ struct UrlState {
   struct timeval expiretime; /* set this with Curl_expire() only */
   struct Curl_tree timenode; /* for the splay stuff */
   struct curl_llist timeoutlist; /* list of pending timeouts */
+  struct time_node expires[EXPIRE_LAST]; /* nodes for each expire type */
 
   /* a place to store the most recently set FTP entrypath */
   char *most_recent_ftp_entrypath;

-- 
To stop receiving notification emails like this one, please contact
address@hidden



reply via email to

[Prev in Thread] Current Thread [Next in Thread]