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