2 * ircd-ratbox: A slightly useful ircd.
3 * s_bsd_poll.c: POSIX poll() compatible network routines.
5 * Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
6 * Copyright (C) 1996-2002 Hybrid Development Team
7 * Copyright (C) 2001 Adrian Chadd <adrian@creative.net.au>
8 * Copyright (C) 2002-2005 ircd-ratbox development team
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
25 * $Id: poll.c 26092 2008-09-19 15:13:52Z androsyn $
27 #include <librb_config.h>
29 #include <commio-int.h>
31 #if defined(HAVE_POLL) && (HAVE_SYS_POLL_H)
35 /* I hate linux -- adrian */
37 #define POLLRDNORM POLLIN
40 #define POLLWRNORM POLLOUT
45 struct pollfd
*pollfds
;
46 int maxindex
; /* highest FD number */
47 int allocated
; /* number of pollfds allocated */
50 typedef struct _pollfd_list pollfd_list_t
;
52 static pollfd_list_t pollfd_list
;
55 rb_setup_fd_poll(rb_fde_t
*F
)
64 * This is a needed exported function which will be called to initialise
65 * the network loop code.
68 rb_init_netio_poll(void)
71 pollfd_list
.pollfds
= rb_malloc(rb_getmaxconnect() * (sizeof(struct pollfd
)));
72 pollfd_list
.allocated
= rb_getmaxconnect();
73 for(fd
= 0; fd
< rb_getmaxconnect(); fd
++)
75 pollfd_list
.pollfds
[fd
].fd
= -1;
77 pollfd_list
.maxindex
= 0;
82 resize_pollarray(int fd
)
84 if(rb_unlikely(fd
>= pollfd_list
.allocated
))
86 int x
, old_value
= pollfd_list
.allocated
;
87 pollfd_list
.allocated
+= 1024;
89 rb_realloc(pollfd_list
.pollfds
,
90 pollfd_list
.allocated
* (sizeof(struct pollfd
)));
91 memset(&pollfd_list
.pollfds
[old_value
+ 1], 0, sizeof(struct pollfd
) * 1024);
92 for(x
= old_value
+ 1; x
< pollfd_list
.allocated
; x
++)
94 pollfd_list
.pollfds
[x
].fd
= -1;
102 * This is a needed exported function which will be called to register
103 * and deregister interest in a pending IO state for a given FD.
106 rb_setselect_poll(rb_fde_t
*F
, unsigned int type
, PF
* handler
, void *client_data
)
111 if(type
& RB_SELECT_READ
)
113 F
->read_handler
= handler
;
114 F
->read_data
= client_data
;
116 F
->pflags
|= POLLRDNORM
;
118 F
->pflags
&= ~POLLRDNORM
;
120 if(type
& RB_SELECT_WRITE
)
122 F
->write_handler
= handler
;
123 F
->write_data
= client_data
;
125 F
->pflags
|= POLLWRNORM
;
127 F
->pflags
&= ~POLLWRNORM
;
129 resize_pollarray(F
->fd
);
133 pollfd_list
.pollfds
[F
->fd
].events
= 0;
134 pollfd_list
.pollfds
[F
->fd
].fd
= -1;
135 if(F
->fd
== pollfd_list
.maxindex
)
137 while(pollfd_list
.maxindex
>= 0
138 && pollfd_list
.pollfds
[pollfd_list
.maxindex
].fd
== -1)
139 pollfd_list
.maxindex
--;
144 pollfd_list
.pollfds
[F
->fd
].events
= F
->pflags
;
145 pollfd_list
.pollfds
[F
->fd
].fd
= F
->fd
;
146 if(F
->fd
> pollfd_list
.maxindex
)
147 pollfd_list
.maxindex
= F
->fd
;
152 /* int rb_select(unsigned long delay)
153 * Input: The maximum time to delay.
154 * Output: Returns -1 on error, 0 on success.
155 * Side-effects: Deregisters future interest in IO and calls the handlers
156 * if an event occurs for an FD.
157 * Comments: Check all connections for new connections and input data
158 * that is to be processed. Also check for connections with data queued
159 * and whether we can write it out.
160 * Called to do the new-style IO, courtesy of squid (like most of this
161 * new IO code). This routine handles the stuff we've hidden in
162 * rb_setselect and fd_table[] and calls callbacks for IO ready
167 rb_select_poll(long delay
)
177 num
= poll(pollfd_list
.pollfds
, pollfd_list
.maxindex
+ 1, delay
);
181 if(!rb_ignore_errno(errno
))
189 /* XXX we *could* optimise by falling out after doing num fds ... */
190 for(ci
= 0; ci
< pollfd_list
.maxindex
+ 1; ci
++)
193 pfd
= &pollfd_list
.pollfds
[ci
];
195 revents
= pfd
->revents
;
197 if(revents
== 0 || fd
== -1)
204 if(revents
& (POLLRDNORM
| POLLIN
| POLLHUP
| POLLERR
))
206 hdl
= F
->read_handler
;
208 F
->read_handler
= NULL
;
214 if(IsFDOpen(F
) && (revents
& (POLLWRNORM
| POLLOUT
| POLLHUP
| POLLERR
)))
216 hdl
= F
->write_handler
;
217 data
= F
->write_data
;
218 F
->write_handler
= NULL
;
219 F
->write_data
= NULL
;
224 if(F
->read_handler
== NULL
)
225 rb_setselect_poll(F
, RB_SELECT_READ
, NULL
, NULL
);
226 if(F
->write_handler
== NULL
)
227 rb_setselect_poll(F
, RB_SELECT_WRITE
, NULL
, NULL
);
233 #else /* poll not supported */
235 rb_init_netio_poll(void)
242 rb_setselect_poll(rb_fde_t
*F
, unsigned int type
, PF
* handler
, void *client_data
)
249 rb_select_poll(long delay
)
256 rb_setup_fd_poll(rb_fde_t
*F
)