fix a bug in liboping that caused 100% cpu utilization in collectd (patch from #6337)
[openwrt/svn-archive/archive.git] / libs / liboping / patches / 100-fd_error.patch
1 diff --git a/src/liboping.c b/src/liboping.c
2 index 411d866..e80ea29 100644
3 --- a/src/liboping.c
4 +++ b/src/liboping.c
5 @@ -590,9 +590,10 @@ static int ping_receive_one (pingobj_t *obj, const pinghost_t *ph,
6
7 static int ping_receive_all (pingobj_t *obj)
8 {
9 - fd_set readfds;
10 - int num_readfds;
11 - int max_readfds;
12 + fd_set read_fds;
13 + fd_set err_fds;
14 + int num_fds;
15 + int max_fd;
16
17 pinghost_t *ph;
18 pinghost_t *ptr;
19 @@ -631,23 +632,25 @@ static int ping_receive_all (pingobj_t *obj)
20
21 while (1)
22 {
23 - FD_ZERO (&readfds);
24 - num_readfds = 0;
25 - max_readfds = -1;
26 + FD_ZERO (&read_fds);
27 + FD_ZERO (&err_fds);
28 + num_fds = 0;
29 + max_fd = -1;
30
31 for (ptr = ph; ptr != NULL; ptr = ptr->next)
32 {
33 if (!timerisset (ptr->timer))
34 continue;
35
36 - FD_SET (ptr->fd, &readfds);
37 - num_readfds++;
38 + FD_SET (ptr->fd, &read_fds);
39 + FD_SET (ptr->fd, &err_fds);
40 + num_fds++;
41
42 - if (max_readfds < ptr->fd)
43 - max_readfds = ptr->fd;
44 + if (max_fd < ptr->fd)
45 + max_fd = ptr->fd;
46 }
47
48 - if (num_readfds == 0)
49 + if (num_fds == 0)
50 break;
51
52 if (gettimeofday (&nowtime, NULL) == -1)
53 @@ -659,11 +662,11 @@ static int ping_receive_all (pingobj_t *obj)
54 if (ping_timeval_sub (&endtime, &nowtime, &timeout) == -1)
55 break;
56
57 - dprintf ("Waiting on %i sockets for %i.%06i seconds\n", num_readfds,
58 + dprintf ("Waiting on %i sockets for %i.%06i seconds\n", num_fds,
59 (int) timeout.tv_sec,
60 (int) timeout.tv_usec);
61
62 - status = select (max_readfds + 1, &readfds, NULL, NULL, &timeout);
63 + status = select (max_fd + 1, &read_fds, NULL, &err_fds, &timeout);
64
65 if (gettimeofday (&nowtime, NULL) == -1)
66 {
67 @@ -696,9 +699,18 @@ static int ping_receive_all (pingobj_t *obj)
68
69 for (ptr = ph; ptr != NULL; ptr = ptr->next)
70 {
71 - if (FD_ISSET (ptr->fd, &readfds))
72 + if (FD_ISSET (ptr->fd, &read_fds))
73 + {
74 if (ping_receive_one (obj, ptr, &nowtime) == 0)
75 ret++;
76 + }
77 + else if (FD_ISSET (ptr->fd, &err_fds))
78 + {
79 + /* clear the timer in this case so that we
80 + * don't run into an endless loop. */
81 + /* TODO: Set an error flag in this case. */
82 + timerclear (ptr->timer);
83 + }
84 }
85 } /* while (1) */
86