X-Git-Url: https://jfr.im/git/irc/rqf/shadowircd.git/blobdiff_plain/94b4fbf93a7653bd9acb52649d6a4a8d5f994d0a..6f187f63b510ade944b8b3704727eeff3f0d31ca:/libratbox/src/ports.c diff --git a/libratbox/src/ports.c b/libratbox/src/ports.c index 0802e1d..9611dd9 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,21 +23,18 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 * USA * - * $Id: ports.c 26092 2008-09-19 15:13:52Z 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; @@ -45,38 +42,18 @@ static port_event_t *pelst; /* port buffer */ static int pemax; /* max structs to buffer */ int -rb_setup_fd_ports(int fd) +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); -} - -/* 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) { @@ -88,6 +65,8 @@ rb_init_netio_ports(void) pelst = rb_malloc(sizeof(port_event_t) * pemax); zero_timespec.tv_sec = 0; zero_timespec.tv_nsec = 0; + rb_set_time(); + return 0; } /* @@ -100,20 +79,35 @@ void 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); F->read_handler = handler; F->read_data = client_data; } if(type & RB_SELECT_WRITE) { - pe_update_events(F, POLLWRNORM, handler); 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); + } /* @@ -129,14 +123,20 @@ int rb_select_ports(long delay) { int i, fd; - uint nget = 1; + int nget = 1; struct timespec poll_time; - struct timer_data *tdata; + struct timespec *p = NULL; + struct ev_entry *ev; - poll_time.tv_sec = delay / 1000; - poll_time.tv_nsec = (delay % 1000) * 1000000; + if(delay >= 0) + { + poll_time.tv_sec = delay / 1000; + poll_time.tv_nsec = (delay % 1000) * 1000000; + p = &poll_time; + } - i = port_getn(pe, pelst, pemax, &nget, &poll_time); + + i = port_getn(pe, pelst, pemax, &nget, p); rb_set_time(); if(i == -1) @@ -144,30 +144,116 @@ rb_select_ports(long delay) for(i = 0; i < nget; i++) { - switch (pelst[i].portev_source) + if(pelst[i].portev_source == PORT_SOURCE_FD) { - case 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 +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) {