fix a bug in liboping that caused 100% cpu utilization in collectd (patch from #6337)
[packages.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