/* * select.C: select(2) socket engine. * * Copyright © 2007 Pippijn van Steenhoven / The Ermyth Team * Rights to this code are as documented in COPYING. * * * Portions of this file were derived from sources bearing the following license: * Rights to this code are documented in doc/pod/license.pod. * Copyright © 2005-2007 Atheme Project (http://www.atheme.org) */ static char const rcsid[] = "$Id: select.C,v 1.7 2007/09/16 18:54:45 pippijn Exp $"; #include "atheme.h" #include "internal.h" #include "datastream.h" fd_set readfds, writefds; /* * init_socket_queues() * * inputs: * none * * outputs: * none * * side effects: * when using select, we don't need to do anything here. */ void init_socket_queues (void) { return; } /* * update_select_sets() * * inputs: * none * * outputs: * none * * side effects: * registered sockets are prepared for the select() loop. */ static void update_select_sets (void) { connection_t::list_type::iterator it = connection_t::list.begin (); connection_t::list_type::iterator et = connection_t::list.end (); connection_t *cptr; FD_ZERO (&readfds); FD_ZERO (&writefds); while (it != et) { cptr = *it; if (cptr->is_connecting ()) FD_SET (cptr->fd, &writefds); else if (cptr->is_listening ()) FD_SET (cptr->fd, &readfds); if (sendq_nonempty (cptr)) FD_SET (cptr->fd, &writefds); else FD_SET (cptr->fd, &readfds); ++it; } } /* * connection_t::select() * * inputs: * delay in nanoseconds * * outputs: * none * * side effects: * registered sockets and their associated handlers are acted on. */ void connection_t::select (time_t delay) { int sr; connection_t::list_type::iterator it = connection_t::list.begin (); connection_t::list_type::iterator et = connection_t::list.end (); connection_t *cptr; timeval to; update_select_sets (); to.tv_sec = 0; to.tv_usec = delay; if ((sr = select (system_state.maxfd + 1, &readfds, &writefds, NULL, &to)) > 0) { /* Iterate twice, so we don't touch freed memory if * a connection is closed. * -- jilles */ while (it != et) { cptr = *it; if (FD_ISSET (cptr->fd, &writefds)) { if (cptr->is_connecting ()) cptr.callback.connected (cptr); else cptr->write_handler (cptr); } ++it; } for (it = connection_t::list.begin (), et = connection_t::list.end (); it != et; ++it) { cptr = *it; if (FD_ISSET (cptr->fd, &readfds)) { cptr->read_handler (cptr); } } for (it = connection_t::list.begin (), et = connection_t::list.end (); it != et; ++it) { cptr = *it; if (cptr->flags & CF_DEAD) cptr->close (); } } else { if (sr == 0) { /* select() timed out */ } else if ((sr == -1) && (errno == EINTR)) { /* some signal interrupted us, restart select() */ } else if (sr == -1) { return; } } } /* vim:cinoptions=>s,e0,n0,f0,{0,}0,^0,=s,ps,t0,c3,+s,(2s,us,)20,*30,gs,hs * vim:ts=8 * vim:sw=8 * vim:noexpandtab */