]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
* released 1.2.5.1 v1.2.5.1
authorwilly tarreau <willy@wtap.(none)>
Sun, 18 Dec 2005 00:13:48 +0000 (01:13 +0100)
committerwilly tarreau <willy@wtap.(none)>
Sun, 18 Dec 2005 00:13:48 +0000 (01:13 +0100)
* dirty hack to fix a bug introduced with epoll : if we close an FD and
  immediately reassign it to another session through a connect(), the
  Prev{Read,Write}Events are not updated, which causes trouble detecting
  changes, thus leading to many timeouts at high loads.

CHANGELOG
haproxy.c

index 7db21e51e1eb024ca77117078e0c5cf2fafdd614..d51cb3eb60790653a41a591bfcb128f114495169 100644 (file)
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,6 +1,12 @@
 ChangeLog :
 ===========
 
+2005/05/02 : 1.2.5.1
+  - dirty hack to fix a bug introduced with epoll : if we close an FD and
+    immediately reassign it to another session through a connect(), the
+    Prev{Read,Write}Events are not updated, which causes trouble detecting
+    changes, thus leading to many timeouts at high loads.
+
 2005/04/30 : 1.2.5 (1.1.31)
   - changed the runtime argument to disable epoll() to '-de'
   - changed the runtime argument to disable poll() to '-dp'
index 301ad25e9f0e2c7a495177d33f2b9a4bdb017f4f..ec726880b9e486ee5f0b29b542177ea728709bcb 100644 (file)
--- a/haproxy.c
+++ b/haproxy.c
@@ -653,6 +653,16 @@ static int stopping = 0;   /* non zero means stopping in progress */
 static struct timeval now = {0,0};     /* the current date at any moment */
 static struct proxy defproxy;          /* fake proxy used to assign default values on all instances */
 
+#if defined(ENABLE_EPOLL)
+/* FIXME: this is dirty, but at the moment, there's no other solution to remove
+ * the old FDs from outside the loop. Perhaps we should export a global 'poll'
+ * structure with pointers to functions such as init_fd() and close_fd(), plus
+ * a private structure with several pointers to places such as below.
+ */
+
+static fd_set *PrevReadEvent = NULL, *PrevWriteEvent = NULL;
+#endif
+
 static regmatch_t pmatch[MAX_MATCH];  /* rm_so, rm_eo for regular expressions */
 /* this is used to drain data, and as a temporary buffer for sprintf()... */
 static char trash[BUFSIZE];
@@ -1413,6 +1423,13 @@ static inline struct timeval *tv_min(struct timeval *tvmin,
 static inline void fd_delete(int fd) {
     FD_CLR(fd, StaticReadEvent);
     FD_CLR(fd, StaticWriteEvent);
+#if defined(ENABLE_EPOLL)
+    if (PrevReadEvent) {
+       FD_CLR(fd, PrevReadEvent);
+       FD_CLR(fd, PrevWriteEvent);
+    }
+#endif
+
     close(fd);
     fdtab[fd].state = FD_STCLOSE;
 
@@ -4695,8 +4712,7 @@ int process_chk(struct task *t) {
                    }
                }
            }
-           //fprintf(stderr, "process_chk: 5\n");
-           close(fd);
+           close(fd); /* socket creation error */
        }
 
        if (!s->result) { /* nothing done */
@@ -4870,8 +4886,6 @@ int epoll_loop(int action) {
   struct epoll_event ev;
 
   /* private data */
-  static int last_maxfd = 0;
-  static fd_set *PrevReadEvent = NULL, *PrevWriteEvent = NULL;
   static struct epoll_event *epoll_events = NULL;
   static int epoll_fd;
 
@@ -4894,7 +4908,6 @@ int epoll_loop(int action) {
       if (PrevReadEvent)  free(PrevReadEvent);
       if (epoll_events)   free(epoll_events);
       close(epoll_fd);
-      last_maxfd = 0;
       epoll_fd = 0;
       return 1;
   }
@@ -4918,20 +4931,6 @@ int epoll_loop(int action) {
       }
 #endif
 
-
-      /*
-       * We'll first check if some fds have been closed recently, in which case
-       * we'll have to remove them from the previous epoll set. It's
-       * unnecessary to call epoll_ctl(DEL) because close() automatically
-       * removes the fds from the epoll set.
-       */
-      for (fd = maxfd; fd < last_maxfd; fd++) {
-         ev.data.fd = fd;
-         FD_CLR(fd, PrevReadEvent);
-         FD_CLR(fd, PrevWriteEvent);
-      }
-      last_maxfd = maxfd;
-
       for (fds = 0; (fds << INTBITS) < maxfd; fds++) {
          
          rn = ((int*)StaticReadEvent)[fds];  ro = ((int*)PrevReadEvent)[fds];