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
26 #include <librb_config.h>
28 #include <commio-int.h>
31 #ifdef HAVE_SYS_POLL_H
36 /* I hate linux -- adrian */
38 #define POLLRDNORM POLLIN
41 #define POLLWRNORM POLLOUT
46 struct pollfd
*pollfds
;
47 int maxindex
; /* highest FD number */
48 int allocated
; /* number of pollfds allocated */
51 typedef struct _pollfd_list pollfd_list_t
;
53 static pollfd_list_t pollfd_list
;
56 rb_setup_fd_poll(rb_fde_t
*F
__attribute__((unused
)))
65 * This is a needed exported function which will be called to initialise
66 * the network loop code.
69 rb_init_netio_poll(void)
72 pollfd_list
.pollfds
= rb_malloc(rb_getmaxconnect() * (sizeof(struct pollfd
)));
73 pollfd_list
.allocated
= rb_getmaxconnect();
74 for(fd
= 0; fd
< rb_getmaxconnect(); fd
++)
76 pollfd_list
.pollfds
[fd
].fd
= -1;
78 pollfd_list
.maxindex
= 0;
83 resize_pollarray(int fd
)
85 if(rb_unlikely(fd
>= pollfd_list
.allocated
))
87 int x
, old_value
= pollfd_list
.allocated
;
88 pollfd_list
.allocated
+= 1024;
90 rb_realloc(pollfd_list
.pollfds
,
91 pollfd_list
.allocated
* (sizeof(struct pollfd
)));
92 memset(&pollfd_list
.pollfds
[old_value
+ 1], 0, sizeof(struct pollfd
) * 1024);
93 for(x
= old_value
+ 1; x
< pollfd_list
.allocated
; x
++)
95 pollfd_list
.pollfds
[x
].fd
= -1;
103 * This is a needed exported function which will be called to register
104 * and deregister interest in a pending IO state for a given FD.
107 rb_setselect_poll(rb_fde_t
*F
, unsigned int type
, PF
* handler
, void *client_data
)
112 if(type
& RB_SELECT_READ
)
114 F
->read_handler
= handler
;
115 F
->read_data
= client_data
;
117 F
->pflags
|= POLLRDNORM
;
119 F
->pflags
&= ~POLLRDNORM
;
121 if(type
& RB_SELECT_WRITE
)
123 F
->write_handler
= handler
;
124 F
->write_data
= client_data
;
126 F
->pflags
|= POLLWRNORM
;
128 F
->pflags
&= ~POLLWRNORM
;
130 resize_pollarray(F
->fd
);
134 pollfd_list
.pollfds
[F
->fd
].events
= 0;
135 pollfd_list
.pollfds
[F
->fd
].fd
= -1;
136 if(F
->fd
== pollfd_list
.maxindex
)
138 while(pollfd_list
.maxindex
>= 0
139 && pollfd_list
.pollfds
[pollfd_list
.maxindex
].fd
== -1)
140 pollfd_list
.maxindex
--;
145 pollfd_list
.pollfds
[F
->fd
].events
= F
->pflags
;
146 pollfd_list
.pollfds
[F
->fd
].fd
= F
->fd
;
147 if(F
->fd
> pollfd_list
.maxindex
)
148 pollfd_list
.maxindex
= F
->fd
;
153 /* int rb_select(unsigned long delay)
154 * Input: The maximum time to delay.
155 * Output: Returns -1 on error, 0 on success.
156 * Side-effects: Deregisters future interest in IO and calls the handlers
157 * if an event occurs for an FD.
158 * Comments: Check all connections for new connections and input data
159 * that is to be processed. Also check for connections with data queued
160 * and whether we can write it out.
161 * Called to do the new-style IO, courtesy of squid (like most of this
162 * new IO code). This routine handles the stuff we've hidden in
163 * rb_setselect and fd_table[] and calls callbacks for IO ready
168 rb_select_poll(long delay
)
178 num
= poll(pollfd_list
.pollfds
, pollfd_list
.maxindex
+ 1, delay
);
182 if(!rb_ignore_errno(errno
))
190 /* XXX we *could* optimise by falling out after doing num fds ... */
191 for(ci
= 0; ci
< pollfd_list
.maxindex
+ 1; ci
++)
194 pfd
= &pollfd_list
.pollfds
[ci
];
196 revents
= pfd
->revents
;
198 if(revents
== 0 || fd
== -1)
205 if(revents
& (POLLRDNORM
| POLLIN
| POLLHUP
| POLLERR
))
207 hdl
= F
->read_handler
;
209 F
->read_handler
= NULL
;
215 if(IsFDOpen(F
) && (revents
& (POLLWRNORM
| POLLOUT
| POLLHUP
| POLLERR
)))
217 hdl
= F
->write_handler
;
218 data
= F
->write_data
;
219 F
->write_handler
= NULL
;
220 F
->write_data
= NULL
;
225 if(F
->read_handler
== NULL
)
226 rb_setselect_poll(F
, RB_SELECT_READ
, NULL
, NULL
);
227 if(F
->write_handler
== NULL
)
228 rb_setselect_poll(F
, RB_SELECT_WRITE
, NULL
, NULL
);