]>
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
28 #include <librb_config.h>
30 #include <commio-int.h>
31 #include <event-int.h>
32 #if defined(HAVE_PORT_H) && (HAVE_PORT_CREATE)
39 static struct timespec zero_timespec
;
41 static port_event_t
*pelst
; /* port buffer */
42 static int pemax
; /* max structs to buffer */
45 rb_setup_fd_ports(rb_fde_t
*F
)
53 * This is a needed exported function which will be called to initialise
54 * the network loop code.
58 rb_init_netio_ports(void)
60 if((pe
= port_create()) < 0)
64 pemax
= getdtablesize();
65 pelst
= rb_malloc(sizeof(port_event_t
) * pemax
);
66 zero_timespec
.tv_sec
= 0;
67 zero_timespec
.tv_nsec
= 0;
75 * This is a needed exported function which will be called to register
76 * and deregister interest in a pending IO state for a given FD.
79 rb_setselect_ports(rb_fde_t
*F
, unsigned int type
, PF
* handler
, void *client_data
)
81 lrb_assert(IsFDOpen(F
));
82 int old_flags
= F
->pflags
;
84 if(type
& RB_SELECT_READ
)
86 F
->read_handler
= handler
;
87 F
->read_data
= client_data
;
89 if(type
& RB_SELECT_WRITE
)
91 F
->write_handler
= handler
;
92 F
->write_data
= client_data
;
96 if(F
->read_handler
!= NULL
)
98 if(F
->write_handler
!= NULL
)
101 if(old_flags
== 0 && F
->pflags
== 0)
103 else if(F
->pflags
<= 0)
105 port_dissociate(pe
, PORT_SOURCE_FD
, F
->fd
);
109 port_associate(pe
, PORT_SOURCE_FD
, F
->fd
, F
->pflags
, F
);
116 * Called to do the new-style IO, courtesy of squid (like most of this
117 * new IO code). This routine handles the stuff we've hidden in
118 * rb_setselect and fd_table[] and calls callbacks for IO ready
123 rb_select_ports(long delay
)
126 unsigned int nget
= 1;
127 struct timespec poll_time
;
128 struct timespec
*p
= NULL
;
133 poll_time
.tv_sec
= delay
/ 1000;
134 poll_time
.tv_nsec
= (delay
% 1000) * 1000000;
139 i
= port_getn(pe
, pelst
, pemax
, &nget
, p
);
145 for(i
= 0; (unsigned)i
< nget
; i
++)
147 if(pelst
[i
].portev_source
== PORT_SOURCE_FD
)
149 fd
= pelst
[i
].portev_object
;
151 rb_fde_t
*F
= pelst
[i
].portev_user
;
152 if((pelst
[i
].portev_events
& (POLLIN
| POLLHUP
| POLLERR
)) && (hdl
= F
->read_handler
))
154 F
->read_handler
= NULL
;
155 hdl(F
, F
->read_data
);
157 if((pelst
[i
].portev_events
& (POLLOUT
| POLLHUP
| POLLERR
)) && (hdl
= F
->write_handler
))
159 F
->write_handler
= NULL
;
160 hdl(F
, F
->write_data
);
162 } else if(pelst
[i
].portev_source
== PORT_SOURCE_TIMER
)
164 ev
= (struct ev_entry
*)pelst
[i
].portev_user
;
165 rb_run_one_event(ev
);
172 rb_ports_supports_event(void)
178 rb_ports_init_event(void)
184 rb_ports_sched_event(struct ev_entry
*event
, int when
)
189 struct itimerspec ts
;
191 event
->comm_ptr
= rb_malloc(sizeof(timer_t
));
192 id
= event
->comm_ptr
;
194 memset(&ev
, 0, sizeof(ev
));
195 ev
.sigev_notify
= SIGEV_PORT
;
196 ev
.sigev_value
.sival_ptr
= ¬
198 memset(¬, 0, sizeof(not));
199 not.portnfy_port
= pe
;
200 not.portnfy_user
= event
;
202 if(timer_create(CLOCK_REALTIME
, &ev
, id
) < 0)
204 rb_lib_log("timer_create: %s\n", strerror(errno
));
208 memset(&ts
, 0, sizeof(ts
));
209 ts
.it_value
.tv_sec
= when
;
210 ts
.it_value
.tv_nsec
= 0;
211 if(event
->frequency
!= 0)
212 ts
.it_interval
= ts
.it_value
;
214 if(timer_settime(*id
, 0, &ts
, NULL
) < 0)
216 rb_lib_log("timer_settime: %s\n", strerror(errno
));
223 rb_ports_unsched_event(struct ev_entry
*event
)
225 timer_delete(*((timer_t
*) event
->comm_ptr
));
226 rb_free(event
->comm_ptr
);
227 event
->comm_ptr
= NULL
;
229 #else /* ports not supported */
232 rb_ports_supports_event(void)
239 rb_ports_init_event(void)
245 rb_ports_sched_event(struct ev_entry
*event
, int when
)
252 rb_ports_unsched_event(struct ev_entry
*event
)
258 rb_init_netio_ports(void)
264 rb_setselect_ports(rb_fde_t
*F
, unsigned int type
, PF
* handler
, void *client_data
)
271 rb_select_ports(long delay
)
278 rb_setup_fd_ports(rb_fde_t
*F
)