* re-architectured the server round-robin mechanism to ease integration of
  other algorithms. It now relies on the number of active and backup servers.
diff --git a/haproxy.c b/haproxy.c
index 68af4e5..0a935c0 100644
--- a/haproxy.c
+++ b/haproxy.c
@@ -1785,57 +1785,81 @@
 
 
 /*
- * This function tries to find a running server for the proxy <px>. A first
- * pass looks for active servers, and if none is found, a second pass also
- * looks for backup servers.
- * If no valid server is found, NULL is returned and px->cursrv is left undefined.
+ * This function recounts the number of usable active and backup servers for
+ * proxy <p>. These numbers are returned into the p->srv_act and p->srv_bck.
+ */
+static inline void recount_servers(struct proxy *px) {
+    struct server *srv;
+
+    px->srv_act = 0; px->srv_bck = 0;
+    for (srv = px->srv; srv != NULL; srv = srv->next) {
+        if (srv->state & SRV_RUNNING) {
+            if (srv->state & SRV_BACKUP)
+                px->srv_bck++;
+            else
+                px->srv_act++;
+        }
+    }
+}
+
+/*
+ * This function tries to find a running server for the proxy <px> following
+ * the round-robin method. Depending on the number of active/backup servers,
+ * it will either look for active servers, or for backup servers.
+ * If any server is found, it will be returned and px->cursrv will be updated
+ * to point to the next server. If no valid server is found, NULL is returned.
  */
-static inline struct server *find_server(struct proxy *px) {
-    struct server *srv = px->cursrv;
+static inline struct server *get_server_rr(struct proxy *px) {
+    struct server *srv;
     struct server *end;
-    int ignore_backup = 1;
 
-    do {
+    if (px->srv_act) {
+        srv = px->cursrv;
 	if (srv == NULL)
 	    srv = px->srv;
         end = srv;
 	do  {
-	    if (srv->state & SRV_RUNNING
-		&& !((srv->state & SRV_BACKUP) && ignore_backup))
+	    if ((srv->state & (SRV_RUNNING | SRV_BACKUP)) == SRV_RUNNING) {
+                px->cursrv = srv->next;
 		return srv;
+            }
+
 	    srv = srv->next;
 	    if (srv == NULL)
 		srv = px->srv;
 	} while (srv != end);
+        /* note that theorically we should not get there */
+    }
 
+    if (px->srv_bck) {
 	/* By default, we look for the first backup server if all others are
 	 * DOWN. But in some cases, it may be desirable to load-balance across
 	 * all backup servers.
 	 */
-	if (!(px->options & PR_O_USE_ALL_BK))
+        if (px->options & PR_O_USE_ALL_BK)
+            srv = px->cursrv;
+        else
+            srv = px->srv;
+
+	if (srv == NULL)
 	    srv = px->srv;
+        end = srv;
+	do  {
+	    if (srv->state & SRV_RUNNING) {
+                px->cursrv = srv->next;
+		return srv;
+            }
+	    srv = srv->next;
+	    if (srv == NULL)
+		srv = px->srv;
+	} while (srv != end);
+        /* note that theorically we should not get there */
+    }
 
-    } while (ignore_backup--);
+    /* if we get there, it means there are no available servers at all */
     return NULL;
 }
 
-/*
- * This function recounts the number of usable active and backup servers for
- * proxy <p>. These numbers are returned into the p->srv_act and p->srv_bck.
- */
-static inline void recount_servers(struct proxy *px) {
-    struct server *srv;
-
-    px->srv_act = 0; px->srv_bck = 0;
-    for (srv = px->srv; srv != NULL; srv = srv->next) {
-        if (srv->state & SRV_RUNNING) {
-            if (srv->state & SRV_BACKUP)
-                px->srv_bck++;
-            else
-                px->srv_act++;
-        }
-    }
-}
 
 /*
  * This function initiates a connection to the current server (s->srv) if (s->direct)
@@ -1860,17 +1884,16 @@
 	s->srv_addr = s->srv->addr;
     }
     else if (s->proxy->options & PR_O_BALANCE) {
+        if (!s->proxy->srv_act && !s->proxy->srv_bck)
+            return SN_ERR_SRVTO;
+
 	if (s->proxy->options & PR_O_BALANCE_RR) {
 	    struct server *srv;
 
-	    srv = find_server(s->proxy);
-
-	    if (srv == NULL) /* no server left */
-		return SN_ERR_SRVTO;
-
+	    srv = get_server_rr(s->proxy);
+            /* srv cannot be NULL */
 	    s->srv_addr = srv->addr;
 	    s->srv = srv;
-	    s->proxy->cursrv = srv->next;
 	}
 	else /* unknown balancing algorithm */
 	    return SN_ERR_INTERNAL;