package: haproxy
[openwrt/svn-archive/archive.git] / net / haproxy / patches / 0002-BUG-MINOR-epoll-correctly-disable-FD-polling-i-1.4.22.diff
1 From 72ce4c8f4e0531c50b3a0914d77858440d16d914 Mon Sep 17 00:00:00 2001
2 From: Willy Tarreau <w@1wt.eu>
3 Date: Thu, 4 Oct 2012 21:54:41 +0200
4 Subject: BUG/MINOR: epoll: correctly disable FD polling in fd_rem()
5
6 When calling fd_rem(), the polling was not correctly disabled because the
7 ->prev state was set to zero instead of the previous value. fd_rem() is
8 very rarely used, only just before closing a socket.
9
10 The effect is that upon an error reported at the connection level, if the
11 task assigned to the connection was too slow to be woken up because of too
12 many other tasks in the run queue, the FD was still not disabled and caused
13 the connection handler to be called again with the same event until the task
14 was finally executed to close the fd.
15
16 This issue only affects the epoll poller, not the sepoll variant nor any of
17 the other ones.
18
19 It was already present in 1.4 and even 1.3 with the same almost unnoticeable
20 effects. The bug can in fact only be discovered during development where it
21 emphasizes other bugs.
22
23 It should be backported anyway.
24 (cherry picked from commit f8cfa447c676849e1d1b007353d4ea2f7231e4a0)
25 ---
26 src/ev_epoll.c | 8 ++++++--
27 1 files changed, 6 insertions(+), 2 deletions(-)
28
29 diff --git a/src/ev_epoll.c b/src/ev_epoll.c
30 index b976868..0b22da6 100644
31 --- a/src/ev_epoll.c
32 +++ b/src/ev_epoll.c
33 @@ -194,11 +194,15 @@ REGPRM2 static int __fd_clr(const int fd, int dir)
34 REGPRM1 static void __fd_rem(int fd)
35 {
36 uint32_t ofs = FD2OFS(fd);
37 + uint32_t old_evt;
38
39 - if (unlikely(!((fd_evts[ofs] >> FD2BIT(fd)) & 3)))
40 + old_evt = fd_evts[ofs] >> FD2BIT(fd);
41 + old_evt &= 3;
42 +
43 + if (unlikely(!old_evt))
44 return;
45
46 - alloc_chg_list(fd, 0);
47 + alloc_chg_list(fd, old_evt);
48 fd_evts[ofs] &= ~FD2MSK(fd);
49 return;
50 }
51 --
52 1.7.1
53