void Selector::add_fd( int fd, IO_FUNC interest ) { // update max_fd (the highest valid index in fd_set's array) and also // make sure we're not overflowing our fd_set // On Windows, we have to check the individual fd_set to see if it's // full. if( fd > max_fd ) { max_fd = fd; } #if !defined(WIN32) if ( fd < 0 || fd >= fd_select_size() ) { EXCEPT( "Selector::add_fd(): fd %d outside valid range 0-%d", fd, _fd_select_size-1 ); } #endif if(IsDebugLevel(D_DAEMONCORE)) { char *fd_description = describe_fd(fd); dprintf(D_FULLDEBUG, "selector %p adding fd %d (%s)\n", this, fd, fd_description); free(fd_description); } switch( interest ) { case IO_READ: #if defined(WIN32) if ( save_read_fds->fd_count >= fd_select_size() ) { EXCEPT( "Selector::add_fd(): read fd_set is full" ); } #endif FD_SET( fd, save_read_fds ); break; case IO_WRITE: #if defined(WIN32) if ( save_write_fds->fd_count >= fd_select_size() ) { EXCEPT( "Selector::add_fd(): write fd_set is full" ); } #endif FD_SET( fd, save_write_fds ); break; case IO_EXCEPT: #if defined(WIN32) if ( save_except_fds->fd_count >= fd_select_size() ) { EXCEPT( "Selector::add_fd(): except fd_set is full" ); } #endif FD_SET( fd, save_except_fds ); break; } }
void Selector::delete_fd( int fd, IO_FUNC interest ) { #if !defined(WIN32) if ( fd < 0 || fd >= fd_select_size() ) { EXCEPT( "Selector::delete_fd(): fd %d outside valid range 0-%d", fd, _fd_select_size-1 ); } #endif m_single_shot = SINGLE_SHOT_SKIP; if (IsDebugLevel(D_DAEMONCORE)) { dprintf(D_DAEMONCORE | D_VERBOSE, "selector %p deleting fd %d\n", this, fd); } switch( interest ) { case IO_READ: FD_CLR( fd, save_read_fds ); break; case IO_WRITE: FD_CLR( fd, save_write_fds ); break; case IO_EXCEPT: FD_CLR( fd, save_except_fds ); break; } }
Selector::Selector() { #if defined(WIN32) // On Windows, we can't treat fd_set as an open-ended bit array. // fd_set can take up to FD_SETSIZE sockets (not any socket whose // fd is <= FD_SETSIZE) and that's it. Currently, we set // FD_SETSIZE to 1024. I'm not sure what we can do if we ever // have more than 1024 sockets to select on. fd_set_size = 1; #else int nfdbits = 8 * sizeof(fd_set); fd_set_size = ( fd_select_size() + (nfdbits - 1) ) / nfdbits; #endif if ( cached_read_fds ) { read_fds = cached_read_fds; write_fds = cached_write_fds; except_fds = cached_except_fds; save_read_fds = cached_save_read_fds; save_write_fds = cached_save_write_fds; save_except_fds = cached_save_except_fds; cached_read_fds = NULL; cached_write_fds = NULL; cached_except_fds = NULL; cached_save_read_fds = NULL; cached_save_write_fds = NULL; cached_save_except_fds = NULL; } else { read_fds = (fd_set *)calloc( fd_set_size, sizeof(fd_set) ); write_fds = (fd_set *)calloc( fd_set_size, sizeof(fd_set) ); except_fds = (fd_set *)calloc( fd_set_size, sizeof(fd_set) ); save_read_fds = (fd_set *)calloc( fd_set_size, sizeof(fd_set) ); save_write_fds = (fd_set *)calloc( fd_set_size, sizeof(fd_set) ); save_except_fds = (fd_set *)calloc( fd_set_size, sizeof(fd_set) ); } reset(); }
bool Selector::fd_ready( int fd, IO_FUNC interest ) { if( state != FDS_READY && state != TIMED_OUT ) { EXCEPT( "Selector::fd_ready() called, but selector not in FDS_READY state" ); } #if !defined(WIN32) // on UNIX, make sure the value of fd makes sense // if ( fd < 0 || fd >= fd_select_size() ) { return false; } #endif switch( interest ) { case IO_READ: return (SINGLE_SHOT_OK == m_single_shot) ? (m_poll.revents & POLLIN) : FD_ISSET( fd, read_fds ); break; case IO_WRITE: return (SINGLE_SHOT_OK == m_single_shot) ? (m_poll.revents & POLLOUT) : FD_ISSET( fd, write_fds ); break; case IO_EXCEPT: return (SINGLE_SHOT_OK == m_single_shot) ? (m_poll.revents & POLLERR) : FD_ISSET( fd, except_fds ); break; } // Can never get here return false; }
BOOLEAN Selector::fd_ready( int fd, IO_FUNC interest ) { if( state != FDS_READY && state != TIMED_OUT ) { EXCEPT( "Selector::fd_ready() called, but selector not in FDS_READY state" ); } #if !defined(WIN32) // on UNIX, make sure the value of fd makes sense // if ( fd < 0 || fd >= fd_select_size() ) { return FALSE; } #endif switch( interest ) { case IO_READ: return FD_ISSET( fd, read_fds ); break; case IO_WRITE: return FD_ISSET( fd, write_fds ); break; case IO_EXCEPT: return FD_ISSET( fd, except_fds ); break; } // Can never get here return FALSE; }
void Selector::add_fd( int fd, IO_FUNC interest ) { // update max_fd (the highest valid index in fd_set's array) and also // make sure we're not overflowing our fd_set // On Windows, we have to check the individual fd_set to see if it's // full. if( fd > max_fd ) { max_fd = fd; } #if !defined(WIN32) if ( fd < 0 || fd >= fd_select_size() ) { EXCEPT( "Selector::add_fd(): fd %d outside valid range 0-%d", fd, _fd_select_size-1 ); } #endif if(IsDebugLevel(D_DAEMONCORE)) { char *fd_description = describe_fd(fd); dprintf(D_DAEMONCORE | D_VERBOSE, "selector %p adding fd %d (%s)\n", this, fd, fd_description); free(fd_description); } bool new_fd = false; if ((m_single_shot == SINGLE_SHOT_OK) && (m_poll.fd != fd)) { new_fd = true; } m_poll.fd = fd; switch( interest ) { case IO_READ: #if defined(WIN32) if ( save_read_fds->fd_count >= fd_select_size() ) { EXCEPT( "Selector::add_fd(): read fd_set is full" ); } #endif m_poll.events |= POLLIN; FD_SET( fd, save_read_fds ); break; case IO_WRITE: #if defined(WIN32) if ( save_write_fds->fd_count >= fd_select_size() ) { EXCEPT( "Selector::add_fd(): write fd_set is full" ); } #endif m_poll.events |= POLLOUT; FD_SET( fd, save_write_fds ); break; case IO_EXCEPT: #if defined(WIN32) if ( save_except_fds->fd_count >= fd_select_size() ) { EXCEPT( "Selector::add_fd(): except fd_set is full" ); } #endif m_poll.events |= POLLERR; FD_SET( fd, save_except_fds ); break; } if ((m_single_shot == SINGLE_SHOT_VIRGIN) || ((m_single_shot == SINGLE_SHOT_OK) && (new_fd == false))) { m_single_shot = SINGLE_SHOT_OK; } else { m_single_shot = SINGLE_SHOT_SKIP; } }