]>
jfr.im git - solanum.git/blob - librb/src/ports.c
2 * ircd-ratbox: A slightly useful ircd.
3 * ports.c: Solaris ports 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-2004,2008 ircd-ratbox development team
9 * Copyright (C) 2005 Edward Brocklesby.
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
26 * $Id: ports.c 26286 2008-12-10 23:28:53Z androsyn $
29 #include <librb_config.h>
31 #include <commio-int.h>
32 #include <event-int.h>
33 #if defined(HAVE_PORT_H) && (HAVE_PORT_CREATE)
40 static struct timespec zero_timespec
;
42 static port_event_t
*pelst
; /* port buffer */
43 static int pemax
; /* max structs to buffer */
46 rb_setup_fd_ports(rb_fde_t
*F
)
54 * This is a needed exported function which will be called to initialise
55 * the network loop code.
59 rb_init_netio_ports(void)
61 if((pe
= port_create()) < 0)
65 pemax
= getdtablesize();
66 pelst
= rb_malloc(sizeof(port_event_t
) * pemax
);
67 zero_timespec
.tv_sec
= 0;
68 zero_timespec
.tv_nsec
= 0;
76 * This is a needed exported function which will be called to register
77 * and deregister interest in a pending IO state for a given FD.
80 rb_setselect_ports(rb_fde_t
*F
, unsigned int type
, PF
* handler
, void *client_data
)
82 lrb_assert(IsFDOpen(F
));
83 int old_flags
= F
->pflags
;
85 if(type
& RB_SELECT_READ
)
87 F
->read_handler
= handler
;
88 F
->read_data
= client_data
;
90 if(type
& RB_SELECT_WRITE
)
92 F
->write_handler
= handler
;
93 F
->write_data
= client_data
;
97 if(F
->read_handler
!= NULL
)
99 if(F
->write_handler
!= NULL
)
100 F
->pflags
|= POLLOUT
;
102 if(old_flags
== 0 && F
->pflags
== 0)
104 else if(F
->pflags
<= 0)
106 port_dissociate(pe
, PORT_SOURCE_FD
, F
->fd
);
110 port_associate(pe
, PORT_SOURCE_FD
, F
->fd
, F
->pflags
, F
);
117 * Called to do the new-style IO, courtesy of squid (like most of this
118 * new IO code). This routine handles the stuff we've hidden in
119 * rb_setselect and fd_table[] and calls callbacks for IO ready
124 rb_select_ports(long delay
)
127 unsigned int nget
= 1;
128 struct timespec poll_time
;
129 struct timespec
*p
= NULL
;
134 poll_time
.tv_sec
= delay
/ 1000;
135 poll_time
.tv_nsec
= (delay
% 1000) * 1000000;
140 i
= port_getn(pe
, pelst
, pemax
, &nget
, p
);
146 for(i
= 0; (unsigned)i
< nget
; i
++)
148 if(pelst
[i
].portev_source
== PORT_SOURCE_FD
)
150 fd
= pelst
[i
].portev_object
;
152 rb_fde_t
*F
= pelst
[i
].portev_user
;
153 if((pelst
[i
].portev_events
& (POLLIN
| POLLHUP
| POLLERR
)) && (hdl
= F
->read_handler
))
155 F
->read_handler
= NULL
;
156 hdl(F
, F
->read_data
);
158 if((pelst
[i
].portev_events
& (POLLOUT
| POLLHUP
| POLLERR
)) && (hdl
= F
->write_handler
))
160 F
->write_handler
= NULL
;
161 hdl(F
, F
->write_data
);
163 } else if(pelst
[i
].portev_source
== PORT_SOURCE_TIMER
)
165 ev
= (struct ev_entry
*)pelst
[i
].portev_user
;
173 rb_ports_supports_event(void)
179 rb_ports_init_event(void)
185 rb_ports_sched_event(struct ev_entry
*event
, int when
)
190 struct itimerspec ts
;
192 event
->comm_ptr
= rb_malloc(sizeof(timer_t
));
193 id
= event
->comm_ptr
;
195 memset(&ev
, 0, sizeof(ev
));
196 ev
.sigev_notify
= SIGEV_PORT
;
197 ev
.sigev_value
.sival_ptr
= ¬
199 memset(¬, 0, sizeof(not));
200 not.portnfy_port
= pe
;
201 not.portnfy_user
= event
;
203 if(timer_create(CLOCK_REALTIME
, &ev
, id
) < 0)
205 rb_lib_log("timer_create: %s\n", strerror(errno
));
209 memset(&ts
, 0, sizeof(ts
));
210 ts
.it_value
.tv_sec
= when
;
211 ts
.it_value
.tv_nsec
= 0;
212 if(event
->frequency
!= 0)
213 ts
.it_interval
= ts
.it_value
;
215 if(timer_settime(*id
, 0, &ts
, NULL
) < 0)
217 rb_lib_log("timer_settime: %s\n", strerror(errno
));
224 rb_ports_unsched_event(struct ev_entry
*event
)
226 timer_delete(*((timer_t
*) event
->comm_ptr
));
227 rb_free(event
->comm_ptr
);
228 event
->comm_ptr
= NULL
;
230 #else /* ports not supported */
233 rb_ports_supports_event(void)
240 rb_ports_init_event(void)
246 rb_ports_sched_event(struct ev_entry
*event
, int when
)
253 rb_ports_unsched_event(struct ev_entry
*event
)
259 rb_init_netio_ports(void)
265 rb_setselect_ports(rb_fde_t
*F
, unsigned int type
, PF
* handler
, void *client_data
)
272 rb_select_ports(long delay
)
279 rb_setup_fd_ports(rb_fde_t
*F
)