ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/trunk/src/s_bsd_poll.c
(Generate patch)

Comparing:
ircd-hybrid/src/s_bsd_poll.c (file contents), Revision 33 by knight, Sun Oct 2 20:50:00 2005 UTC vs.
ircd-hybrid/trunk/src/s_bsd_poll.c (file contents), Revision 8941 by michael, Sat Apr 27 23:46:13 2019 UTC

# Line 1 | Line 1
1   /*
2 < *  ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd).
3 < *  s_bsd_poll.c: POSIX poll() compatible network routines.
2 > *  ircd-hybrid: an advanced, lightweight Internet Relay Chat Daemon (ircd)
3   *
4 < *  Originally by Adrian Chadd <adrian@creative.net.au>
6 < *  Copyright (C) 2002 Hybrid Development Team
4 > *  Copyright (c) 2000-2019 ircd-hybrid development team
5   *
6   *  This program is free software; you can redistribute it and/or modify
7   *  it under the terms of the GNU General Public License as published by
# Line 17 | Line 15
15   *
16   *  You should have received a copy of the GNU General Public License
17   *  along with this program; if not, write to the Free Software
18 < *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
18 > *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
19   *  USA
20 < *
21 < *  $Id$
20 > */
21 >
22 > /*! \file s_bsd_poll.c
23 > * \brief POSIX poll() compatible network routines.
24 > * \version $Id$
25   */
26  
27   #include "stdinc.h"
28 + #if USE_IOPOLL_MECHANISM == __IOPOLL_MECHANISM_POLL
29   #include <sys/poll.h>
30   #include "fdlist.h"
31 < #include "hook.h"
31 > #include "list.h"
32 > #include "memory.h"
33   #include "ircd.h"
34   #include "s_bsd.h"
35 < #include "s_log.h"
35 > #include "log.h"
36  
37   /* I hate linux -- adrian */
38   #ifndef POLLRDNORM
# Line 39 | Line 42
42   #define POLLWRNORM POLLOUT
43   #endif
44  
45 + static int pollfds_size;
46   static struct pollfd *pollfds;
47 < static int pollmax = -1;  /* highest FD number */
44 < static dlink_node *hookptr;
47 > static int pollnum;
48  
46 /*
47 * changing_fdlimit
48 *
49 * Resize pollfds array if necessary.
50 */
51 static void *
52 changing_fdlimit(va_list args)
53 {
54  int old_fdlimit = hard_fdlimit;
55
56  pass_callback(hookptr, va_arg(args, int));
57
58  if (hard_fdlimit != old_fdlimit)
59    pollfds = MyRealloc(pollfds, sizeof(struct pollfd) * hard_fdlimit);
60
61  return NULL;
62 }
49  
50   /*
51 < * init_netio
51 > * comm_select_init
52   *
53   * This is a needed exported function which will be called to initialise
54   * the network loop code.
55   */
56   void
57 < init_netio(void)
57 > comm_select_init(void)
58   {
59 <  int fd;
60 <
75 <  pollfds = MyMalloc(sizeof(struct pollfd) * hard_fdlimit);
76 <
77 <  for (fd = 0; fd < hard_fdlimit; fd++)
78 <    pollfds[fd].fd = -1;
79 <
80 <  hookptr = install_hook(fdlimit_cb, changing_fdlimit);
81 < }
82 <
83 < /*
84 < * find a spare slot in the fd list. We can optimise this out later!
85 < *   -- adrian
86 < */
87 < static inline int
88 < poll_findslot(void)
89 < {
90 <  int i;
91 <
92 <  for (i = 0; i < hard_fdlimit; i++)
93 <    if (pollfds[i].fd == -1)
94 <    {
95 <      /* MATCH!!#$*&$ */
96 <      return i;
97 <    }
98 <
99 <  assert(1 == 0);
100 <  /* NOTREACHED */
101 <  return -1;
59 >  pollfds_size = hard_fdlimit;
60 >  pollfds = xcalloc(sizeof(struct pollfd) * pollfds_size);
61   }
62  
63   /*
# Line 108 | Line 67 | poll_findslot(void)
67   * and deregister interest in a pending IO state for a given FD.
68   */
69   void
70 < comm_setselect(fde_t *F, unsigned int type, PF *handler,
71 <               void *client_data, time_t timeout)
72 < {  
70 > comm_setselect(fde_t *F, unsigned int type, void (*handler)(fde_t *, void *),
71 >               void *client_data, uintmax_t timeout)
72 > {
73    int new_events;
74  
75 +  assert(F);
76 +  assert(F->flags.open == true);
77 +
78    if ((type & COMM_SELECT_READ))
79    {
80      F->read_handler = handler;
# Line 126 | Line 88 | comm_setselect(fde_t *F, unsigned int ty
88    }
89  
90    new_events = (F->read_handler ? POLLRDNORM : 0) |
91 <    (F->write_handler ? POLLWRNORM : 0);
91 >               (F->write_handler ? POLLWRNORM : 0);
92  
93 <  if (timeout != 0)
94 <    F->timeout = CurrentTime + (timeout / 1000);
93 >  if (timeout)
94 >  {
95 >    F->timeout = event_base->time.sec_monotonic + timeout;
96 >    F->timeout_handler = handler;
97 >    F->timeout_data = client_data;
98 >  }
99  
100    if (new_events != F->evcache)
101    {
102      if (new_events == 0)
103      {
104 <      pollfds[F->comm_index].fd = -1;
105 <      pollfds[F->comm_index].revents = 0;
104 >      if (F->comm_index != pollnum - 1)
105 >      {
106 >        fde_t *other = &fd_table[pollfds[pollnum - 1].fd];
107 >
108 >        pollfds[F->comm_index].fd = pollfds[pollnum - 1].fd;
109 >        pollfds[F->comm_index].events = pollfds[pollnum - 1].events;
110 >        pollfds[F->comm_index].revents = pollfds[pollnum - 1].revents;
111  
112 <      if (pollmax == F->comm_index)
113 <        while (pollmax >= 0 && pollfds[pollmax].fd == -1)
114 <          pollmax--;
112 >        assert(other);
113 >        other->comm_index = F->comm_index;
114 >      }
115 >
116 >      F->comm_index = -1;
117 >      --pollnum;
118      }
119      else
120      {
121        if (F->evcache == 0)
122        {
123 <        F->comm_index = poll_findslot();
124 <        if (F->comm_index > pollmax)
125 <          pollmax = F->comm_index;
123 >        if (pollnum >= pollfds_size)
124 >        {
125 >          pollfds_size *= 2;
126 >          pollfds = xrealloc(pollfds, sizeof(struct pollfd) * pollfds_size);
127 >        }
128  
129 <        pollfds[F->comm_index].fd = F->fd;
129 >        F->comm_index = pollnum++;
130 >        pollfds[F->comm_index].fd = F->fd;
131        }
132 +
133        pollfds[F->comm_index].events = new_events;
134        pollfds[F->comm_index].revents = 0;
135      }
# Line 159 | Line 137 | comm_setselect(fde_t *F, unsigned int ty
137      F->evcache = new_events;
138    }
139   }
140 <
140 >
141   /*
142   * comm_select
143   *
# Line 171 | Line 149 | comm_setselect(fde_t *F, unsigned int ty
149   void
150   comm_select(void)
151   {
152 <  int num, ci, revents;
153 <  PF *hdl;
176 <  fde_t *F;
152 >  int num;
153 >  void (*hdl)(fde_t *, void *);
154  
155 <  /* XXX kill that +1 later ! -- adrian */
179 <  num = poll(pollfds, pollmax + 1, SELECT_DELAY);
155 >  num = poll(pollfds, pollnum, SELECT_DELAY);
156  
157 <  set_time();
157 >  event_time_set();
158  
159    if (num < 0)
160    {
161 < #ifdef HAVE_USLEEP
162 <    usleep(50000);  /* avoid 99% CPU in comm_select */
187 < #endif
161 >    const struct timespec req = { .tv_sec = 0, .tv_nsec = 50000000 };
162 >    nanosleep(&req, NULL);  /* Avoid 99% CPU in comm_select */
163      return;
164    }
165  
166 <  for (ci = 0; ci <= pollmax && num > 0; ci++)
166 >  for (int ci = 0; ci < pollnum && num > 0; ++ci)
167    {
168 <    if ((revents = pollfds[ci].revents) == 0 || pollfds[ci].fd == -1)
168 >    int revents = pollfds[ci].revents;
169 >    if (revents == 0)
170        continue;
195    num--;
171  
172 <    F = lookup_fd(pollfds[ci].fd);
173 <    if (F == NULL || !F->flags.open)
172 >    --num;
173 >
174 >    fde_t *F = &fd_table[pollfds[ci].fd];
175 >
176 >    if (F->flags.open == false)
177        continue;
178  
179      if (revents & (POLLRDNORM | POLLIN | POLLHUP | POLLERR))
180 <      if ((hdl = F->read_handler) != NULL)
180 >    {
181 >      if ((hdl = F->read_handler))
182        {
183          F->read_handler = NULL;
184          hdl(F, F->read_data);
185 <        if (!F->flags.open)
186 <          continue;
185 >
186 >        if (F->flags.open == false)
187 >          continue;
188        }
189 +    }
190  
191      if (revents & (POLLWRNORM | POLLOUT | POLLHUP | POLLERR))
192 <      if ((hdl = F->write_handler) != NULL)
192 >    {
193 >      if ((hdl = F->write_handler))
194        {
195          F->write_handler = NULL;
196          hdl(F, F->write_data);
197 <        if (!F->flags.open)
198 <          continue;
197 >
198 >        if (F->flags.open == false)
199 >          continue;
200        }
201 +    }
202  
203      comm_setselect(F, 0, NULL, NULL, 0);
204    }
205   }
206 + #endif

Comparing:
ircd-hybrid/src/s_bsd_poll.c (property svn:keywords), Revision 33 by knight, Sun Oct 2 20:50:00 2005 UTC vs.
ircd-hybrid/trunk/src/s_bsd_poll.c (property svn:keywords), Revision 8941 by michael, Sat Apr 27 23:46:13 2019 UTC

# Line 1 | Line 1
1 < Id Revision
1 > Id

Diff Legend

Removed lines
+ Added lines
< Changed lines (old)
> Changed lines (new)