]> granicus.if.org Git - libevent/commitdiff
support retrying for connections; from dug song
authorNiels Provos <provos@gmail.com>
Sat, 9 Dec 2006 01:41:57 +0000 (01:41 +0000)
committerNiels Provos <provos@gmail.com>
Sat, 9 Dec 2006 01:41:57 +0000 (01:41 +0000)
small tweaks from me.

svn:r297

evhttp.h
http-internal.h
http.c

index c26fbb8d6dcd567a40fabf3dad2dc413cba043ed..6fa3e9760a796a5a0bb03573f2b431ea119f7896 100644 (file)
--- a/evhttp.h
+++ b/evhttp.h
@@ -160,6 +160,10 @@ void evhttp_connection_free(struct evhttp_connection *evcon);
 void evhttp_connection_set_timeout(struct evhttp_connection *evcon,
     int timeout_in_secs);
 
+/* Sets the retry limit for this connection - -1 repeats indefnitely */
+void evhttp_connection_set_retries(struct evhttp_connection *evcon,
+    int retry_max);
+
 /* The connection gets ownership of the request */
 int evhttp_make_request(struct evhttp_connection *evcon,
     struct evhttp_request *req,
index a7cefbf8f2f9d890821e436c45eff527e844b26c..69fc39ae3212b1fb7090cebbdc039504362b3345 100644 (file)
@@ -53,6 +53,8 @@ struct evhttp_connection {
 #define EVHTTP_CON_CLOSEDETECT  0x0004  /* detecting if persistent close */
 
        int timeout;                    /* timeout in seconds for events */
+       int retry_cnt;                  /* retry count */
+       int retry_max;                  /* maximum number of retries */
        
        enum evhttp_connection_state state;
 
diff --git a/http.c b/http.c
index 3ef226419d5e05123d5aff85ca84c38a76f43117..123b1c21c8e9cd7b34d8cd853602e24184f8e8b8 100644 (file)
--- a/http.c
+++ b/http.c
@@ -733,6 +733,15 @@ evhttp_connection_stop_detectclose(struct evhttp_connection *evcon)
        event_del(&evcon->ev);
 }
 
+static void
+evhttp_connection_retry(int fd, short what, void *arg)
+{
+       struct evhttp_connection *evcon = arg;
+
+       evcon->state = EVCON_DISCONNECTED;
+       evhttp_connection_connect(evcon);
+}
+
 /*
  * Call back for asynchronous connection attempt.
  */
@@ -769,6 +778,8 @@ evhttp_connectioncb(int fd, short what, void *arg)
        event_debug(("%s: connected to \"%s:%d\" on %d\n",
                        __func__, evcon->address, evcon->port, evcon->fd));
 
+       /* Reset the retry count as we were successful in connecting */
+       evcon->retry_cnt = 0;
        evcon->state = EVCON_CONNECTED;
 
        /* try to start requests that have queued up on this connection */
@@ -776,6 +787,13 @@ evhttp_connectioncb(int fd, short what, void *arg)
        return;
 
  cleanup:
+       if (evcon->retry_max < 0 || evcon->retry_cnt < evcon->retry_max) {
+               evtimer_set(&evcon->ev, evhttp_connection_retry, evcon);
+               evhttp_add_event(&evcon->ev, 2 << evcon->retry_cnt,
+                   HTTP_CONNECT_TIMEOUT);
+               evcon->retry_cnt++;
+               return;
+       }
        evhttp_connection_reset(evcon);
 
        /* for now, we just signal all requests by executing their callbacks */
@@ -1188,6 +1206,7 @@ evhttp_connection_new(const char *address, unsigned short port)
        evcon->port = port;
 
        evcon->timeout = -1;
+       evcon->retry_cnt = evcon->retry_max = 0;
 
        if ((evcon->address = strdup(address)) == NULL) {
                event_warn("%s: strdup failed", __func__);
@@ -1222,6 +1241,13 @@ evhttp_connection_set_timeout(struct evhttp_connection *evcon,
        evcon->timeout = timeout_in_secs;
 }
 
+void
+evhttp_connection_set_retries(struct evhttp_connection *evcon,
+    int retry_max)
+{
+       evcon->retry_max = retry_max;
+}
+
 int
 evhttp_connection_connect(struct evhttp_connection *evcon)
 {