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