/* * RageIRCd: an advanced Internet Relay Chat daemon (ircd). * (C) 2000-2005 the RageIRCd Development Team, all rights reserved. * * This software is free, licensed under the General Public License. * Please refer to doc/LICENSE and doc/README for further details. * * $Id: fd.c,v 1.20.2.1 2004/12/07 03:05:11 pneumatus Exp $ */ #include "struct.h" #include "common.h" #include "sys.h" #include "h.h" #include "fd.h" #include "memory.h" #include "numeric.h" fd_entry fd_table[MAXCONNECTIONS]; fd_stat fds; static inline void fd_clear(fd_entry *fde) { fde->fd = FD_UNUSED; fde->open = 0; #if defined(USE_POLL) || defined(USE_RTSIGIO) fde->index = FD_UNUSED; #endif #if defined(USE_EPOLL) fde->epoll_state = 0; #endif ClrCallback(fde->read); ClrCallback(fde->write); ClrCallback(fde->connect); ClrCallback(fde->timeout); ClrCallback(fde->flush); fde->timeout_time = 0; fde->flush_time = 0; fde->ip.sin_addr.s_addr = 0; fde->dns_query = NULL; } static void fd_check_highest(int fd, int opening) { if (fds.highest > fd) { return; } if (fd > fds.highest) { ASSERT(opening); fds.highest = fd; } else { ASSERT(!opening); while (fds.highest >= 0 && !fd_table[fds.highest].open) { fds.highest--; } } } void fd_init() { int i; memset(fd_table, '\0', sizeof(fd_entry) * MAXCONNECTIONS); for (i = 0; i < MAXCONNECTIONS; i++) { fd_table[i].fd = FD_UNUSED; #if defined(USE_POLL) || defined(USE_RTSIGIO) fd_table[i].index = FD_UNUSED; #endif } memset(&fds, '\0', sizeof(fd_stat)); fds.highest = -1; fds.count = 0; } void fd_open(int fd) { fd_entry *fde = &fd_table[fd]; ASSERT(!fde->open); ASSERT(fde->fd == FD_UNUSED); fde->fd = fd; fde->open = 1; fd_check_highest(fd, 1); fds.count++; } void fd_close(int fd) { fd_entry *fde = &fd_table[fd]; ASSERT(fde->open); ASSERT(fde->fd > FD_UNUSED); engine_set_call(fd, FDEV_READ|FDEV_WRITE, NULL, NULL, 0); fd_clear(fde); fd_check_highest(fd, 0); fds.count--; close(fd); }