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>
30 #if defined(HAVE_POLL) && (HAVE_SYS_POLL_H)
34 /* I hate linux -- adrian */
36 #define POLLRDNORM POLLIN
39 #define POLLWRNORM POLLOUT
44 struct pollfd
*pollfds
;
45 int maxindex
; /* highest FD number */
46 int allocated
; /* number of pollfds allocated */
49 typedef struct _pollfd_list pollfd_list_t
;
51 static pollfd_list_t pollfd_list
;
54 rb_setup_fd_poll(rb_fde_t
*F
)
63 * This is a needed exported function which will be called to initialise
64 * the network loop code.
67 rb_init_netio_poll(void)
70 pollfd_list
.pollfds
= rb_malloc(rb_getmaxconnect() * (sizeof(struct pollfd
)));
71 pollfd_list
.allocated
= rb_getmaxconnect();
72 for(fd
= 0; fd
< rb_getmaxconnect(); fd
++)
74 pollfd_list
.pollfds
[fd
].fd
= -1;
76 pollfd_list
.maxindex
= 0;
81 resize_pollarray(int fd
)
83 if(rb_unlikely(fd
>= pollfd_list
.allocated
))
85 int x
, old_value
= pollfd_list
.allocated
;
86 pollfd_list
.allocated
+= 1024;
88 rb_realloc(pollfd_list
.pollfds
,
89 pollfd_list
.allocated
* (sizeof(struct pollfd
)));
90 memset(&pollfd_list
.pollfds
[old_value
+ 1], 0, sizeof(struct pollfd
) * 1024);
91 for(x
= old_value
+ 1; x
< pollfd_list
.allocated
; x
++)
93 pollfd_list
.pollfds
[x
].fd
= -1;
101 * This is a needed exported function which will be called to register
102 * and deregister interest in a pending IO state for a given FD.
105 rb_setselect_poll(rb_fde_t
*F
, unsigned int type
, PF
* handler
, void *client_data
)
110 if(type
& RB_SELECT_READ
)
112 F
->read_handler
= handler
;
113 F
->read_data
= client_data
;
115 F
->pflags
|= POLLRDNORM
;
117 F
->pflags
&= ~POLLRDNORM
;
119 if(type
& RB_SELECT_WRITE
)
121 F
->write_handler
= handler
;
122 F
->write_data
= client_data
;
124 F
->pflags
|= POLLWRNORM
;
126 F
->pflags
&= ~POLLWRNORM
;
128 resize_pollarray(F
->fd
);
132 pollfd_list
.pollfds
[F
->fd
].events
= 0;
133 pollfd_list
.pollfds
[F
->fd
].fd
= -1;
134 if(F
->fd
== pollfd_list
.maxindex
)
136 while(pollfd_list
.maxindex
>= 0
137 && pollfd_list
.pollfds
[pollfd_list
.maxindex
].fd
== -1)
138 pollfd_list
.maxindex
--;
143 pollfd_list
.pollfds
[F
->fd
].events
= F
->pflags
;
144 pollfd_list
.pollfds
[F
->fd
].fd
= F
->fd
;
145 if(F
->fd
> pollfd_list
.maxindex
)
146 pollfd_list
.maxindex
= F
->fd
;
151 /* int rb_select(unsigned long delay)
152 * Input: The maximum time to delay.
153 * Output: Returns -1 on error, 0 on success.
154 * Side-effects: Deregisters future interest in IO and calls the handlers
155 * if an event occurs for an FD.
156 * Comments: Check all connections for new connections and input data
157 * that is to be processed. Also check for connections with data queued
158 * and whether we can write it out.
159 * Called to do the new-style IO, courtesy of squid (like most of this
160 * new IO code). This routine handles the stuff we've hidden in
161 * rb_setselect and fd_table[] and calls callbacks for IO ready
166 rb_select_poll(long delay
)
176 num
= poll(pollfd_list
.pollfds
, pollfd_list
.maxindex
+ 1, delay
);
180 if(!rb_ignore_errno(errno
))
188 /* XXX we *could* optimise by falling out after doing num fds ... */
189 for(ci
= 0; ci
< pollfd_list
.maxindex
+ 1; ci
++)
192 pfd
= &pollfd_list
.pollfds
[ci
];
194 revents
= pfd
->revents
;
196 if(revents
== 0 || fd
== -1)
203 if(revents
& (POLLRDNORM
| POLLIN
| POLLHUP
| POLLERR
))
205 hdl
= F
->read_handler
;
207 F
->read_handler
= NULL
;
213 if(IsFDOpen(F
) && (revents
& (POLLWRNORM
| POLLOUT
| POLLHUP
| POLLERR
)))
215 hdl
= F
->write_handler
;
216 data
= F
->write_data
;
217 F
->write_handler
= NULL
;
218 F
->write_data
= NULL
;
223 if(F
->read_handler
== NULL
)
224 rb_setselect_poll(F
, RB_SELECT_READ
, NULL
, NULL
);
225 if(F
->write_handler
== NULL
)
226 rb_setselect_poll(F
, RB_SELECT_WRITE
, NULL
, NULL
);
232 #else /* poll not supported */
234 rb_init_netio_poll(void)
241 rb_setselect_poll(rb_fde_t
*F
, unsigned int type
, PF
* handler
, void *client_data
)
248 rb_select_poll(long delay
)
255 rb_setup_fd_poll(rb_fde_t
*F
)