00001 /* -*- C++ -*- */ 00002 00003 //============================================================================= 00004 /** 00005 * @file Handle_Set.h 00006 * 00007 * $Id: Handle_Set.h 82723 2008-09-16 09:35:44Z johnnyw $ 00008 * 00009 * @author Douglas C. Schmidt <schmidt@cs.wustl.edu> 00010 */ 00011 //============================================================================= 00012 00013 #ifndef ACE_HANDLE_SET_H 00014 #define ACE_HANDLE_SET_H 00015 #include /**/ "ace/pre.h" 00016 00017 #include /**/ "ace/ACE_export.h" 00018 00019 #if !defined (ACE_LACKS_PRAGMA_ONCE) 00020 # pragma once 00021 #endif /* ACE_LACKS_PRAGMA_ONCE */ 00022 00023 #include "ace/os_include/sys/os_select.h" 00024 #include "ace/os_include/os_limits.h" 00025 00026 // Default size of the ACE Reactor. 00027 #if defined (FD_SETSIZE) 00028 int const ACE_FD_SETSIZE = FD_SETSIZE; 00029 #else /* !FD_SETSIZE */ 00030 # define ACE_FD_SETSIZE FD_SETSIZE 00031 #endif /* ACE_FD_SETSIZE */ 00032 00033 #if !defined (ACE_DEFAULT_SELECT_REACTOR_SIZE) 00034 # define ACE_DEFAULT_SELECT_REACTOR_SIZE ACE_FD_SETSIZE 00035 #endif /* ACE_DEFAULT_SELECT_REACTOR_SIZE */ 00036 00037 ACE_BEGIN_VERSIONED_NAMESPACE_DECL 00038 00039 /** 00040 * @class ACE_Handle_Set 00041 * 00042 * @brief C++ wrapper facade for the socket @c fd_set abstraction. 00043 * 00044 * This abstraction is a very efficient wrapper facade over 00045 * @c fd_set. In particular, no range checking is performed, so 00046 * it's important not to set or clear bits that are outside the 00047 * @c ACE_DEFAULT_SELECT_REACTOR_SIZE. 00048 */ 00049 class ACE_Export ACE_Handle_Set 00050 { 00051 public: 00052 friend class ACE_Handle_Set_Iterator; 00053 00054 // = Initialization and termination. 00055 00056 enum 00057 { 00058 MAXSIZE = ACE_DEFAULT_SELECT_REACTOR_SIZE 00059 }; 00060 00061 // = Initialization methods. 00062 /// Constructor, initializes the bitmask to all 0s. 00063 ACE_Handle_Set (void); 00064 00065 /** 00066 * Constructor, initializes the handle set from a given mask. 00067 */ 00068 ACE_Handle_Set (const fd_set &mask); 00069 00070 // = Methods for manipulating bitsets. 00071 /// Initialize the bitmask to all 0s and reset the associated fields. 00072 void reset (void); 00073 00074 /** 00075 * Checks whether @a handle is enabled. No range checking is 00076 * performed so @a handle must be less than 00077 * @c ACE_DEFAULT_SELECT_REACTOR_SIZE. 00078 */ 00079 int is_set (ACE_HANDLE handle) const; 00080 00081 /// Enables the @a handle. No range checking is performed so @a handle 00082 /// must be less than @c ACE_DEFAULT_SELECT_REACTOR_SIZE. 00083 void set_bit (ACE_HANDLE handle); 00084 00085 /// Disables the @a handle. No range checking is performed so 00086 /// @a handle must be less than @c ACE_DEFAULT_SELECT_REACTOR_SIZE. 00087 void clr_bit (ACE_HANDLE handle); 00088 00089 /// Returns a count of the number of enabled bits. 00090 int num_set (void) const; 00091 00092 /// Returns the number of the large bit. 00093 ACE_HANDLE max_set (void) const; 00094 00095 /** 00096 * Rescan the underlying @c fd_set up to handle @a max to find the new 00097 * <max_handle> (highest bit set) and <size> (how many bits set) values. 00098 * This is useful for evaluating the changes after the handle set has 00099 * been manipulated in some way other than member functions; for example, 00100 * after <select> modifies the @c fd_set. 00101 */ 00102 void sync (ACE_HANDLE max); 00103 00104 /// Returns a pointer to the underlying @c fd_set. Returns 0 if 00105 /// there are no handle bits set (<size_> == 0). 00106 operator fd_set *(); 00107 00108 /// Returns a pointer to the underlying @c fd_set. Returns 0 if 00109 /// there are no handle bits set (<size_> == 0). 00110 fd_set *fdset (void); 00111 00112 #if defined (ACE_HAS_BIG_FD_SET) 00113 /// Assignment operator optimizes for cases where <size_> == 0. 00114 ACE_Handle_Set & operator= (const ACE_Handle_Set &); 00115 #endif /* ACE_HAS_BIG_FD_SET */ 00116 00117 /// Dump the state of an object. 00118 void dump (void) const; 00119 00120 /// Declare the dynamic allocation hooks. 00121 ACE_ALLOC_HOOK_DECLARE; 00122 00123 private: 00124 /// Size of the set, i.e., a count of the number of enabled bits. 00125 int size_; 00126 00127 /// Current max handle. 00128 ACE_HANDLE max_handle_; 00129 00130 #if defined (ACE_HAS_BIG_FD_SET) 00131 /// Current min handle. 00132 ACE_HANDLE min_handle_; 00133 #endif /* ACE_HAS_BIG_FD_SET */ 00134 00135 /// Bitmask. 00136 fd_set mask_; 00137 00138 enum 00139 { 00140 WORDSIZE = NFDBITS, 00141 #if !defined (ACE_WIN32) 00142 NUM_WORDS = howmany (MAXSIZE, NFDBITS), 00143 #endif /* ACE_WIN32 */ 00144 NBITS = 256 00145 }; 00146 00147 /// Counts the number of bits enabled in N. Uses a table lookup to 00148 /// speed up the count. 00149 static int count_bits (u_long n); 00150 00151 #if defined (ACE_HAS_BIG_FD_SET) 00152 /// Find the position of the bit counting from right to left. 00153 static int bitpos (u_long bit); 00154 #endif /* ACE_HAS_BIG_FD_SET */ 00155 00156 /// Resets the <max_handle_> after a clear of the original 00157 /// <max_handle_>. 00158 void set_max (ACE_HANDLE max); 00159 00160 /// Table that maps bytes to counts of the enabled bits in each value 00161 /// from 0 to 255. 00162 static const char nbits_[NBITS]; 00163 }; 00164 00165 /** 00166 * @class ACE_Handle_Set_Iterator 00167 * 00168 * @brief Iterator for the ACE_Handle_Set abstraction. 00169 */ 00170 class ACE_Export ACE_Handle_Set_Iterator 00171 { 00172 public: 00173 /// Constructor. 00174 ACE_Handle_Set_Iterator (const ACE_Handle_Set &hs); 00175 00176 /// Default dtor. 00177 ~ACE_Handle_Set_Iterator (void); 00178 00179 /// Reset the state of the iterator by reinitializing the state 00180 /// that we maintain. 00181 void reset_state (void); 00182 00183 /** 00184 * "Next" operator. Returns the next unseen ACE_HANDLE in the 00185 * <Handle_Set> up to <handle_set_.max_handle_>). When all the 00186 * handles have been seen returns <ACE_INVALID_HANDLE>. Advances 00187 * the iterator automatically, so you need not call <operator++> 00188 * (which is now obsolete). 00189 */ 00190 ACE_HANDLE operator () (void); 00191 00192 /// Dump the state of an object. 00193 void dump (void) const; 00194 00195 /// Declare the dynamic allocation hooks. 00196 ACE_ALLOC_HOOK_DECLARE; 00197 00198 private: 00199 /// The <Handle_Set> we are iterating through. 00200 const ACE_Handle_Set &handles_; 00201 00202 /// Index of the bit we're examining in the current <word_num_> word. 00203 #if defined (ACE_WIN32) 00204 u_int handle_index_; 00205 #elif !defined (ACE_HAS_BIG_FD_SET) 00206 int handle_index_; 00207 #elif defined (ACE_HAS_BIG_FD_SET) 00208 int handle_index_; 00209 u_long oldlsb_; 00210 #endif /* ACE_WIN32 */ 00211 00212 /// Number of the word we're iterating over (typically between 0..7). 00213 int word_num_; 00214 00215 #if defined (ACE_HAS_BIG_FD_SET) 00216 /// Number max of the words with a possible bit on. 00217 int word_max_; 00218 #endif /* ACE_HAS_BIG_FD_SET */ 00219 00220 #if !defined (ACE_WIN32) && !defined (ACE_HAS_BIG_FD_SET) 00221 /// Value of the bits in the word we're iterating on. 00222 fd_mask word_val_; 00223 #elif !defined (ACE_WIN32) && defined (ACE_HAS_BIG_FD_SET) 00224 /// Value of the bits in the word we're iterating on. 00225 u_long word_val_; 00226 #endif /* !ACE_WIN32 && !ACE_HAS_BIG_FD_SET */ 00227 }; 00228 00229 ACE_END_VERSIONED_NAMESPACE_DECL 00230 00231 #if defined (__ACE_INLINE__) 00232 #include "ace/Handle_Set.inl" 00233 #endif /* __ACE_INLINE__ */ 00234 00235 #include /**/ "ace/post.h" 00236 #endif /* ACE_HANDLE_SET */