⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 select.cc

📁 This Source-Navigator, an IDE for C/C++/Fortran/Java/Tcl/PHP/Python and a host of other languages.
💻 CC
字号:
// $Header: /cvsroot/sourcenav/src/snavigator/demo/c++_demo/glish/Select.cc,v 1.1.1.1 2002/04/18 23:35:25 mdejong Exp $#include "system.h"#include <stdio.h>#include <osfcn.h>#include <errno.h>#include <sys/types.h>#include <sys/socket.h>#include <sys/resource.h>#ifdef HAVE_X11_FD_H#include <X11/fd.h>#endif#ifdef SOLARIS#include <sys/time.h>#include <string.h>extern "C" int gettimeofday( struct timeval *, struct timezone * );#endif#include "Select.h"void gripe( const char* msg );// Increment a timeval by the given amount.void increment_time( struct timeval& t, const struct timeval& incr )	{	t.tv_sec += incr.tv_sec;	t.tv_usec += incr.tv_usec;	while ( t.tv_usec >= 1000000 )		{		++t.tv_sec;		t.tv_usec -= 1000000;		}	}// Decrement a timeval by the given amount.void decrement_time( struct timeval& t, const struct timeval& decr )	{	t.tv_sec -= decr.tv_sec;	t.tv_usec -= decr.tv_usec;	while ( t.tv_usec < 0 )		{		--t.tv_sec;		t.tv_usec += 1000000;		}	}// Returns true if t1 is chronologically less than t2, false otherwise.int time_less_than( const struct timeval& t1, const struct timeval& t2 )	{	return t1.tv_sec < t2.tv_sec ||		(t1.tv_sec == t2.tv_sec && t1.tv_usec < t2.tv_usec);	}Selectee::~Selectee()	{	}SelectTimer::SelectTimer( struct timeval* delta, struct timeval* interval )	{	Init( delta, interval );	}SelectTimer::SelectTimer( long delta_sec, long delta_usec,			long interval_sec, long interval_usec )	{	struct timeval delta;	delta.tv_sec = delta_sec;	delta.tv_usec = delta_usec;	struct timeval interval;	interval.tv_sec = interval_sec;	interval.tv_usec = interval_usec;	Init( &delta, &interval );	}SelectTimer::~SelectTimer()	{	}void SelectTimer::Init( struct timeval* delta, struct timeval* interval )	{	if ( gettimeofday( &exp_t, (struct timezone *) 0 ) < 0 )		gripe( "gettimeofday failed" );	increment_time( exp_t, *delta );	if ( interval )		interval_t = *interval;	else		interval_t.tv_sec = interval_t.tv_usec = 0;	}int SelectTimer::Expired()	{	if ( DoExpiration() &&	     (interval_t.tv_sec > 0 || interval_t.tv_usec > 0) )		{		increment_time( exp_t, interval_t );		return 1;		}	return 0;	}int SelectTimer::DoExpiration()	{	return 1;	}Selector::Selector()	{#ifdef HAVE_SETRLIMIT	struct rlimit rl;	if ( getrlimit( RLIMIT_NOFILE, &rl ) < 0 )		gripe( "getrlimit() failed" );	max_num_fds = int( rl.rlim_max );#else	max_num_fds = 32;#endif	selectees = new Selectee* [max_num_fds];	for ( int i = 0; i < max_num_fds; ++i )		selectees[i] = 0;	current_selectee = 0;	nuke_current_selectee = 0;	fdset = new fd_set;	FD_ZERO( fdset );	}Selector::~Selector()	{	for ( int i = 0; i < max_num_fds; ++i )		delete selectees[i];	delete selectees;	delete fdset;	}void Selector::AddSelectee( Selectee* s )	{	selectees[s->FD()] = s;	FD_SET( s->FD(), fdset );	}void Selector::DeleteSelectee( int selectee_fd )	{	if ( ! FD_ISSET( selectee_fd, fdset ) )		gripe( "non-existent selectee in RemoveSelectee()" );	Selectee* s = selectees[selectee_fd];	if ( s == current_selectee )		// Don't delete it right now, while it's in use, just		// flag that we should do so when we're done with it.		nuke_current_selectee = 1;	else		delete s;	selectees[selectee_fd] = 0;	FD_CLR( selectee_fd, fdset );	}Selectee* Selector::FindSelectee( int selectee_fd ) const	{	if ( ! FD_ISSET( selectee_fd, fdset ) )		return 0;	return selectees[selectee_fd];	}void Selector::AddTimer( SelectTimer* t )	{	timers.append( t );	}int Selector::DoSelection()	{	struct timeval* timeout = 0;	struct timeval timeout_buf;	struct timeval min_t;	if ( timers.length() > 0 )		{		int have_min = 0;		for ( int i = 0; i < timers.length(); ++i )			{			struct timeval timer_t = timers[i]->ExpirationTime();			if ( ! have_min )				{				min_t = timer_t;				have_min = 1;				}			else				{				if ( time_less_than( timer_t, min_t ) )					min_t = timer_t;				}			}		if ( ! have_min )			gripe( "internal consistency problem" );		struct timeval t;		if ( gettimeofday( &t, (struct timezone *) 0 ) < 0 )			gripe( "gettimeofday failed" );		timeout = &timeout_buf;		*timeout = min_t;		// Convert the timeout to a delta from the current time.		if ( time_less_than( *timeout, t ) )			{ // Don't decrement the timeout, it'll go negative.			timeout->tv_sec = timeout->tv_usec = 0;			}		else			decrement_time( *timeout, t );		}	fd_set read_mask = *fdset;	int status;	if ( (status =	      select( FD_SETSIZE, &read_mask, (fd_set *) 0, (fd_set *) 0,		      timeout )) < 0 )		{		if ( errno != EINTR )			gripe( "error in DoSelection()" );		return 0;		}	if ( status == 0 )		{ // Timeout expired.  Assume current time is min_t.		for ( int i = 0; i < timers.length(); ++i )			{			struct timeval timer_t = timers[i]->ExpirationTime();			if ( ! time_less_than( min_t, timer_t ) )				// timer_t <= min_t				if ( ! timers[i]->Expired() )					{					// Timer is now inactive.					timers.remove_nth( i );					--i;	// because loop's about to ++					}			}		}	for ( int i = 0; status > 0 && i < max_num_fds; ++i )		{		if ( FD_ISSET( i, &read_mask ) )			{			current_selectee = selectees[i];			nuke_current_selectee = 0;			int selectee_value =				current_selectee->NotifyOfSelection();			if ( nuke_current_selectee )				delete current_selectee;			current_selectee = 0;			if ( selectee_value )				return selectee_value;			--status;			}		}	if ( status != 0 )		gripe( "inconsistency in DoSelection()" );	return 0;	}void gripe( const char* msg )	{	fprintf( stderr, "Selector/Selectee/SelectTimer error: %s\n", msg );	perror( "perror value" );	exit( 1 );	}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -