On Sun, 2002-11-24 at 21:22, Hugo Duncan wrote:
> > is_set -> count (I'm not fussed about this one)
> Not sure about "count", how about something like "active" 

Yes, or "contains"?

> > Also for library implementors I think we need
> > update_width()
> > To be called after the OS has updated the fd_set
> 
> I saw this in ACE, but couldn't quite work out what it
> was doing?

I have not looked at the code but from what I read in C++NP it scans
fd_set for the highest file_descriptor.  I have attached the
implementation of file_descriptor_set I have been using in my code
recently.  It needs optimization and I haven't got around to doing the
iterator stuff.

C++NP also points out that knowing the width is important for optimizing
size() an the iterator code.  My understanding is that it doesn't much
matter on win32 as the structure of fd_set is different.

I think ACE is an almost perfect model for what we want.  The main
things I would like to see done differently in boost are

1) Use namespaces.
2) Support exception handling.
3) Use std containers.
3) Use other boost libraries.

Section A.6.3 in C++NP describes the reasoning behind the absence of
exceptions.  But as I described in another post I think we can use a
policy class to support a nothrow interface for people who need it.

Hamish



#ifndef IO_FILE_DESCRIPTOR_SET_H
#define IO_FILE_DESCRIPTOR_SET_H

#ifndef _WIN32
#include <sys/select.h>
#else
#include <winsock.h>
#endif

namespace io
{

#ifdef _WIN32
	typedef SOCKET file_descriptor_type;
#else
	typedef int file_descriptor_type;
#endif

class file_descriptor_set : boost::noncopyable
{
public:
	typedef file_descriptor_type value_type;

	file_descriptor_set()
#ifndef _WIN32
		: max_( 0 )
#endif
	{
		FD_ZERO( &fd_set_ );
	}
	void insert( value_type fd )
	{
#ifndef _WIN32
		max_ = std::max( max_, fd );
#endif		
		FD_SET( fd, &fd_set_ );
	}
	void erase( value_type fd )
	{
		FD_CLR( fd, &fd_set_ );
#ifndef _WIN32
		if( fd == max_ )
		{
			--max_;
			recalc_max();
		}
#endif
	}
	bool count( value_type fd )
	{
		return (FD_ISSET( fd, &fd_set_ ) != 0) ? 1 : 0;
	}
	
private:
	fd_set fd_set_;
	friend int select( 
		file_descriptor_set & read_set, 
		file_descriptor_set & write_set, 
		file_descriptor_set & except_set,
		timeval *timeout = 0 )
	{
		int max_max = std::max( read_set.max(), std::max( write_set.max(), except_set.max() ) );
		int ret = ::select( max_max + 1, &read_set.fd_set_, &write_set.fd_set_, &except_set.fd_set_, timeout );
		read_set.recalc_max();
		write_set.recalc_max();
		except_set.recalc_max();
		return ret;
	}
	friend int select( 
		file_descriptor_set & read_set, 
		file_descriptor_set & write_set, 
		timeval *timeout = 0 )
	{
		int max_max = std::max( read_set.max(), write_set.max() );		
		int ret = ::select( max_max + 1, &read_set.fd_set_, &write_set.fd_set_, 0, timeout );
		read_set.recalc_max();
		write_set.recalc_max();
		return ret;
	}

	void recalc_max()
	{
#ifndef _WIN32
		while( max_ != 0 && count( max_ ) == 0 )
		{
			--max_;
		}
#endif
	}
	
#ifndef _WIN32
	value_type max_;
	int max() const { return max_; }
#else
	int max() const { return 0; }
#endif
};

}

#endif
_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

Reply via email to