X-Git-Url: https://jfr.im/git/irc/rqf/shadowircd.git/blobdiff_plain/143b6cc1e4a8faa8181301bf43ddafecab3237cc..36fb4e9a7743326d1a2ca7601bc9bf1c5b9a0bcb:/libratbox/src/ports.c diff --git a/libratbox/src/ports.c b/libratbox/src/ports.c index 353b07b..607fb8c 100644 --- a/libratbox/src/ports.c +++ b/libratbox/src/ports.c @@ -5,7 +5,7 @@ * Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center * Copyright (C) 1996-2002 Hybrid Development Team * Copyright (C) 2001 Adrian Chadd - * Copyright (C) 2002-2004 ircd-ratbox development team + * Copyright (C) 2002-2004,2008 ircd-ratbox development team * Copyright (C) 2005 Edward Brocklesby. * * This program is free software; you can redistribute it and/or modify @@ -23,70 +23,51 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 * USA * - * $Id: ports.c 25038 2008-01-23 16:03:08Z androsyn $ + * $Id: ports.c 26286 2008-12-10 23:28:53Z androsyn $ */ #include #include #include - +#include #if defined(HAVE_PORT_H) && (HAVE_PORT_CREATE) #include - #define PE_LENGTH 128 -static void pe_update_events(rb_fde_t *, short, PF *); static int pe; static struct timespec zero_timespec; static port_event_t *pelst; /* port buffer */ static int pemax; /* max structs to buffer */ -int +int rb_setup_fd_ports(rb_fde_t *F) { - return 0; -} - - -static void -pe_update_events(rb_fde_t * F, short filter, PF * handler) -{ - PF *cur_handler = NULL; - - if (filter == POLLRDNORM) - cur_handler = F->read_handler; - else if (filter == POLLWRNORM) - cur_handler = F->write_handler; - - if (!cur_handler && handler) - port_associate(pe, PORT_SOURCE_FD, F->fd, filter, F); - else if (cur_handler && !handler) - port_dissociate(pe, PORT_SOURCE_FD, F->fd); + return 0; } -/* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */ -/* Public functions */ - - /* * rb_init_netio * * This is a needed exported function which will be called to initialise * the network loop code. */ + int rb_init_netio_ports(void) { - if((pe = port_create()) < 0) { + if((pe = port_create()) < 0) + { return errno; } pemax = getdtablesize(); pelst = rb_malloc(sizeof(port_event_t) * pemax); zero_timespec.tv_sec = 0; zero_timespec.tv_nsec = 0; + rb_set_time(); + return 0; } /* @@ -96,22 +77,38 @@ rb_init_netio_ports(void) * and deregister interest in a pending IO state for a given FD. */ void -rb_setselect_ports(rb_fde_t *F, unsigned int type, PF * handler, - void *client_data) +rb_setselect_ports(rb_fde_t *F, unsigned int type, PF * handler, void *client_data) { lrb_assert(IsFDOpen(F)); + int old_flags = F->pflags; - /* Update the list, even though we're not using it .. */ - if(type & RB_SELECT_READ) { - pe_update_events(F, POLLRDNORM, handler); + if(type & RB_SELECT_READ) + { F->read_handler = handler; F->read_data = client_data; } - if(type & RB_SELECT_WRITE) { - pe_update_events(F, POLLWRNORM, handler); + if(type & RB_SELECT_WRITE) + { F->write_handler = handler; F->write_data = client_data; } + F->pflags = 0; + + if(F->read_handler != NULL) + F->pflags = POLLIN; + if(F->write_handler != NULL) + F->pflags |= POLLOUT; + + if(old_flags == 0 && F->pflags == 0) + return; + else if(F->pflags <= 0) + { + port_dissociate(pe, PORT_SOURCE_FD, F->fd); + return; + } + + port_associate(pe, PORT_SOURCE_FD, F->fd, F->pflags, F); + } /* @@ -126,43 +123,139 @@ rb_setselect_ports(rb_fde_t *F, unsigned int type, PF * handler, int rb_select_ports(long delay) { - int i, fd; - uint nget = 1; -struct timespec poll_time; -struct timer_data *tdata; + int i, fd; + int nget = 1; + struct timespec poll_time; + struct timespec *p = NULL; + struct ev_entry *ev; + + if(delay >= 0) + { + poll_time.tv_sec = delay / 1000; + poll_time.tv_nsec = (delay % 1000) * 1000000; + p = &poll_time; + } - poll_time.tv_sec = delay / 1000; - poll_time.tv_nsec = (delay % 1000) * 1000000; - i = port_getn(pe, pelst, pemax, &nget, &poll_time); + i = port_getn(pe, pelst, pemax, &nget, p); rb_set_time(); - if (i == -1) + if(i == -1) return RB_OK; - for (i = 0; i < nget; i++) { - switch(pelst[i].portev_source) { - case PORT_SOURCE_FD: + for(i = 0; i < nget; i++) + { + if(pelst[i].portev_source == PORT_SOURCE_FD) + { fd = pelst[i].portev_object; PF *hdl = NULL; - rb_fde_t *F = rb_find_fd(fd); - - if ((pelst[i].portev_events & POLLRDNORM) && (hdl = F->read_handler)) { + rb_fde_t *F = pelst[i].portev_user; + if((pelst[i].portev_events & (POLLIN | POLLHUP | POLLERR)) && (hdl = F->read_handler)) + { F->read_handler = NULL; hdl(F, F->read_data); } - if ((pelst[i].portev_events & POLLWRNORM) && (hdl = F->write_handler)) { + if((pelst[i].portev_events & (POLLOUT | POLLHUP | POLLERR)) && (hdl = F->write_handler)) + { F->write_handler = NULL; hdl(F, F->write_data); } - break; + } else if(pelst[i].portev_source == PORT_SOURCE_TIMER) + { + ev = (struct ev_entry *)pelst[i].portev_user; + rb_run_event(ev); } } return RB_OK; } +int +rb_ports_supports_event(void) +{ + return 1; +}; + +void +rb_ports_init_event(void) +{ + return; +} + +int +rb_ports_sched_event(struct ev_entry *event, int when) +{ + timer_t *id; + struct sigevent ev; + port_notify_t not; + struct itimerspec ts; + + event->comm_ptr = rb_malloc(sizeof(timer_t)); + id = event->comm_ptr; + + memset(&ev, 0, sizeof(ev)); + ev.sigev_notify = SIGEV_PORT; + ev.sigev_value.sival_ptr = ¬ + + memset(¬, 0, sizeof(not)); + not.portnfy_port = pe; + not.portnfy_user = event; + + if(timer_create(CLOCK_REALTIME, &ev, id) < 0) + { + rb_lib_log("timer_create: %s\n", strerror(errno)); + return 0; + } + + memset(&ts, 0, sizeof(ts)); + ts.it_value.tv_sec = when; + ts.it_value.tv_nsec = 0; + if(event->frequency != 0) + ts.it_interval = ts.it_value; + + if(timer_settime(*id, 0, &ts, NULL) < 0) + { + rb_lib_log("timer_settime: %s\n", strerror(errno)); + return 0; + } + return 1; +} + +void +rb_ports_unsched_event(struct ev_entry *event) +{ + timer_delete(*((timer_t *) event->comm_ptr)); + rb_free(event->comm_ptr); + event->comm_ptr = NULL; +} #else /* ports not supported */ -int + +int +rb_ports_supports_event(void) +{ + errno = ENOSYS; + return 0; +} + +void +rb_ports_init_event(void) +{ + return; +} + +int +rb_ports_sched_event(struct ev_entry *event, int when) +{ + errno = ENOSYS; + return -1; +} + +void +rb_ports_unsched_event(struct ev_entry *event) +{ + return; +} + +int rb_init_netio_ports(void) { return ENOSYS; @@ -171,23 +264,23 @@ rb_init_netio_ports(void) void rb_setselect_ports(rb_fde_t *F, unsigned int type, PF * handler, void *client_data) { - errno = ENOSYS; - return; + errno = ENOSYS; + return; } - + int rb_select_ports(long delay) { - errno = ENOSYS; - return -1; + errno = ENOSYS; + return -1; } - + int rb_setup_fd_ports(rb_fde_t *F) { - errno = ENOSYS; - return -1; + errno = ENOSYS; + return -1; } - + #endif