mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2025-08-07 07:37:02 +02:00
* released 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.
This commit is contained in:
parent
64a3cc3660
commit
08dedbe898
@ -1,6 +1,12 @@
|
|||||||
ChangeLog :
|
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)
|
2005/04/30 : 1.2.5 (1.1.31)
|
||||||
- changed the runtime argument to disable epoll() to '-de'
|
- changed the runtime argument to disable epoll() to '-de'
|
||||||
- changed the runtime argument to disable poll() to '-dp'
|
- changed the runtime argument to disable poll() to '-dp'
|
||||||
|
37
haproxy.c
37
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 timeval now = {0,0}; /* the current date at any moment */
|
||||||
static struct proxy defproxy; /* fake proxy used to assign default values on all instances */
|
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 */
|
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()... */
|
/* this is used to drain data, and as a temporary buffer for sprintf()... */
|
||||||
static char trash[BUFSIZE];
|
static char trash[BUFSIZE];
|
||||||
@ -1413,6 +1423,13 @@ static inline struct timeval *tv_min(struct timeval *tvmin,
|
|||||||
static inline void fd_delete(int fd) {
|
static inline void fd_delete(int fd) {
|
||||||
FD_CLR(fd, StaticReadEvent);
|
FD_CLR(fd, StaticReadEvent);
|
||||||
FD_CLR(fd, StaticWriteEvent);
|
FD_CLR(fd, StaticWriteEvent);
|
||||||
|
#if defined(ENABLE_EPOLL)
|
||||||
|
if (PrevReadEvent) {
|
||||||
|
FD_CLR(fd, PrevReadEvent);
|
||||||
|
FD_CLR(fd, PrevWriteEvent);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
close(fd);
|
close(fd);
|
||||||
fdtab[fd].state = FD_STCLOSE;
|
fdtab[fd].state = FD_STCLOSE;
|
||||||
|
|
||||||
@ -4695,8 +4712,7 @@ int process_chk(struct task *t) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//fprintf(stderr, "process_chk: 5\n");
|
close(fd); /* socket creation error */
|
||||||
close(fd);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!s->result) { /* nothing done */
|
if (!s->result) { /* nothing done */
|
||||||
@ -4870,8 +4886,6 @@ int epoll_loop(int action) {
|
|||||||
struct epoll_event ev;
|
struct epoll_event ev;
|
||||||
|
|
||||||
/* private data */
|
/* private data */
|
||||||
static int last_maxfd = 0;
|
|
||||||
static fd_set *PrevReadEvent = NULL, *PrevWriteEvent = NULL;
|
|
||||||
static struct epoll_event *epoll_events = NULL;
|
static struct epoll_event *epoll_events = NULL;
|
||||||
static int epoll_fd;
|
static int epoll_fd;
|
||||||
|
|
||||||
@ -4894,7 +4908,6 @@ int epoll_loop(int action) {
|
|||||||
if (PrevReadEvent) free(PrevReadEvent);
|
if (PrevReadEvent) free(PrevReadEvent);
|
||||||
if (epoll_events) free(epoll_events);
|
if (epoll_events) free(epoll_events);
|
||||||
close(epoll_fd);
|
close(epoll_fd);
|
||||||
last_maxfd = 0;
|
|
||||||
epoll_fd = 0;
|
epoll_fd = 0;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -4918,20 +4931,6 @@ int epoll_loop(int action) {
|
|||||||
}
|
}
|
||||||
#endif
|
#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++) {
|
for (fds = 0; (fds << INTBITS) < maxfd; fds++) {
|
||||||
|
|
||||||
rn = ((int*)StaticReadEvent)[fds]; ro = ((int*)PrevReadEvent)[fds];
|
rn = ((int*)StaticReadEvent)[fds]; ro = ((int*)PrevReadEvent)[fds];
|
||||||
|
Loading…
Reference in New Issue
Block a user