00001 
00002 
00003 
00004 #include "ace/Handle_Set.h"
00005 
00006 #if !defined (__ACE_INLINE__)
00007 #include "ace/Handle_Set.inl"
00008 #endif 
00009 
00010 #include "ace/OS_NS_string.h"
00011 
00012 ACE_RCSID(ace, Handle_Set, "$Id: Handle_Set.cpp 79134 2007-07-31 18:23:50Z johnnyw $")
00013 
00014 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
00015 
00016 ACE_ALLOC_HOOK_DEFINE(ACE_Handle_Set)
00017 
00018   
00019   
00020 #if defined (ACE_WIN32)
00021    
00022 #  define ACE_MSB_MASK (~(1 << (NFDBITS - 1)))
00023 #else  
00024 #  define ACE_MSB_MASK (~((fd_mask) 1 << (NFDBITS - 1)))
00025 #endif 
00026 
00027 #if defined (__BORLANDC__) && !defined (ACE_WIN32)
00028 
00029 #define fds_bits __fds_bits
00030 #endif
00031 
00032 #if defined (linux) && __GLIBC__ > 1 && __GLIBC_MINOR__ >= 1 && !defined (_XOPEN_SOURCE)
00033   
00034   
00035   
00036 #define fds_bits __fds_bits
00037 #endif  
00038 
00039 void
00040 ACE_Handle_Set::dump (void) const
00041 {
00042 #if defined (ACE_HAS_DUMP)
00043   ACE_TRACE ("ACE_Handle_Set::dump");
00044 
00045   ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
00046 
00047   ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\nsize_ = %d"), this->size_));
00048   ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\nmax_handle_ = %d"), this->max_handle_));
00049   ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\n[ ")));
00050 
00051 #if defined (ACE_WIN32)
00052   for (size_t i = 0; i < (size_t) this->mask_.fd_count + 1; i++)
00053     ACE_DEBUG ((LM_DEBUG, ACE_TEXT (" %x "), this->mask_.fd_array[i]));
00054 #else 
00055   for (ACE_HANDLE i = 0; i < this->max_handle_ + 1; i++)
00056     if (this->is_set (i))
00057       ACE_DEBUG ((LM_DEBUG, ACE_TEXT (" %d "), i));
00058 #endif 
00059 
00060   ACE_DEBUG ((LM_DEBUG, ACE_TEXT (" ]\n")));
00061   ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP));
00062 #endif 
00063 }
00064 
00065 
00066 
00067 
00068 
00069 
00070 
00071 
00072 
00073 
00074 
00075 
00076 
00077 const char ACE_Handle_Set::nbits_[256] =
00078 {
00079   0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4,
00080   1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
00081   1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
00082   2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
00083   1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
00084   2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
00085   2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
00086   3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
00087   1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
00088   2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
00089   2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
00090   3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
00091   2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
00092   3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
00093   3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
00094   4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8};
00095 
00096 
00097 
00098 ACE_Handle_Set::ACE_Handle_Set (void)
00099 {
00100   ACE_TRACE ("ACE_Handle_Set::ACE_Handle_Set");
00101   this->reset ();
00102 }
00103 
00104 ACE_Handle_Set::ACE_Handle_Set (const fd_set &fd_mask)
00105 {
00106   ACE_TRACE ("ACE_Handle_Set::ACE_Handle_Set");
00107   this->reset ();
00108   ACE_OS::memcpy ((void *) &this->mask_,
00109                   (void *) &fd_mask,
00110                   sizeof this->mask_);
00111 #if !defined (ACE_WIN32)
00112   this->sync (ACE_Handle_Set::MAXSIZE);
00113 #if defined (ACE_HAS_BIG_FD_SET)
00114   this->min_handle_ = 0;
00115 #endif 
00116 #endif 
00117 }
00118 
00119 
00120 
00121 
00122 int
00123 ACE_Handle_Set::count_bits (u_long n)
00124 {
00125 
00126  ACE_TRACE ("ACE_Handle_Set::count_bits");
00127 #if defined (ACE_HAS_HANDLE_SET_OPTIMIZED_FOR_SELECT)
00128   register int rval = 0;
00129 
00130   
00131   
00132 
00133   for (register u_long m = n;
00134        m != 0;
00135        m &= m - 1)
00136     rval++;
00137 
00138   return rval;
00139 #else
00140    return (ACE_Handle_Set::nbits_[n & 0xff]
00141           + ACE_Handle_Set::nbits_[(n >> 8) & 0xff]
00142           + ACE_Handle_Set::nbits_[(n >> 16) & 0xff]
00143           + ACE_Handle_Set::nbits_[(n >> 24) & 0xff]);
00144 #endif 
00145 }
00146 
00147 #if defined (ACE_HAS_BIG_FD_SET)
00148 
00149 
00150 
00151 int
00152 ACE_Handle_Set::bitpos (u_long bit)
00153 {
00154   register int l = 0;
00155   register u_long n = bit - 1;
00156 
00157   
00158 
00159   while (n >> 8)
00160     {
00161       n >>= 8;
00162       l += 8;
00163     }
00164 
00165   
00166   if (n & 16)
00167     {
00168       n >>= 4;
00169       l += 4;
00170     }
00171 
00172   
00173   while (n != 0)
00174     {
00175       n &= n - 1;
00176       l++;
00177     }
00178   return l;
00179 }
00180 #endif 
00181 
00182 
00183 
00184 #if defined (ACE_USE_SHIFT_FOR_EFFICIENCY)
00185 
00186 
00187 
00188 
00189 #define ACE_DIV_BY_WORDSIZE(x) ((x) >> ((int) ACE_Handle_Set::WORDSIZE))
00190 #define ACE_MULT_BY_WORDSIZE(x) ((x) << ((int) ACE_Handle_Set::WORDSIZE))
00191 #else
00192 #define ACE_DIV_BY_WORDSIZE(x) ((x) / ((int) ACE_Handle_Set::WORDSIZE))
00193 #define ACE_MULT_BY_WORDSIZE(x) ((x) * ((int) ACE_Handle_Set::WORDSIZE))
00194 #endif 
00195 
00196 void
00197 ACE_Handle_Set::sync (ACE_HANDLE max)
00198 {
00199   ACE_TRACE ("ACE_Handle_Set::sync");
00200 #if !defined (ACE_WIN32)
00201   fd_mask *maskp = (fd_mask *)(this->mask_.fds_bits);
00202   this->size_ = 0;
00203 
00204   for (int i = ACE_DIV_BY_WORDSIZE (max - 1);
00205        i >= 0;
00206        i--)
00207     this->size_ += ACE_Handle_Set::count_bits (maskp[i]);
00208 
00209   this->set_max (max);
00210 #else
00211   ACE_UNUSED_ARG (max);
00212 #endif 
00213 }
00214 
00215 
00216 
00217 void
00218 ACE_Handle_Set::set_max (ACE_HANDLE current_max)
00219 {
00220   ACE_TRACE ("ACE_Handle_Set::set_max");
00221 #if !defined(ACE_WIN32)
00222   fd_mask * maskp = (fd_mask *)(this->mask_.fds_bits);
00223 
00224   if (this->size_ == 0)
00225     this->max_handle_ = ACE_INVALID_HANDLE;
00226   else
00227     {
00228       int i;
00229 
00230       for (i = ACE_DIV_BY_WORDSIZE (current_max - 1);
00231            maskp[i] == 0;
00232            i--)
00233         continue;
00234 #if defined (ACE_TANDEM_NSK_BIT_ORDER)
00235       
00236       this->max_handle_ = ACE_MULT_BY_WORDSIZE (i);
00237       for (fd_mask val = maskp[i];
00238            (val & ACE_MSB_MASK) != 0;
00239            val = (val << 1))
00240         ++this->max_handle_;
00241 #elif 1 
00242       this->max_handle_ = ACE_MULT_BY_WORDSIZE (i);
00243       for (fd_mask val = maskp[i];
00244            (val & ~1) != 0; 
00245            val = (val >> 1) & ACE_MSB_MASK)
00246         ++this->max_handle_;
00247 #else
00248       register u_long val = this->mask_.fds_bits[i];
00249       this->max_handle_ = ACE_MULT_BY_WORDSIZE (i)
00250         + ACE_Handle_Set::bitpos(val & ~(val - 1));
00251 #endif 
00252     }
00253 
00254   
00255   if (this->max_handle_ >= ACE_Handle_Set::MAXSIZE)
00256     this->max_handle_ = ACE_Handle_Set::MAXSIZE - 1;
00257 #else
00258   ACE_UNUSED_ARG (current_max);
00259 #endif 
00260 }
00261 
00262 ACE_ALLOC_HOOK_DEFINE(ACE_Handle_Set_Iterator)
00263 
00264 void
00265 ACE_Handle_Set_Iterator::dump (void) const
00266 {
00267 #if defined (ACE_HAS_DUMP)
00268   ACE_TRACE ("ACE_Handle_Set_Iterator::dump");
00269 
00270   ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
00271 #if defined(ACE_WIN32) || !defined(ACE_HAS_BIG_FD_SET)
00272   ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\nhandle_index_ = %d"), this->handle_index_));
00273 #elif defined(ACE_HAS_BIG_FD_SET)
00274   ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\nword_max_ = %d"), this->word_max_));
00275   ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\nword_val_ = %d"), this->word_val_));
00276 #endif
00277   ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\nword_num_ = %d"), this->word_num_));
00278   ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP));
00279 #endif 
00280 }
00281 
00282 ACE_HANDLE
00283 ACE_Handle_Set_Iterator::operator () (void)
00284 {
00285   ACE_TRACE ("ACE_Handle_Set_Iterator::operator");
00286 #if defined (ACE_WIN32)
00287   if (this->handle_index_ < this->handles_.mask_.fd_count)
00288     
00289     return (ACE_HANDLE) this->handles_.mask_.fd_array[this->handle_index_++];
00290   else
00291     return ACE_INVALID_HANDLE;
00292 
00293 #elif !defined (ACE_HAS_BIG_FD_SET) 
00294   
00295   ACE_HANDLE maxhandlep1 = this->handles_.max_handle_ + 1;
00296 
00297   
00298   
00299   
00300   
00301   
00302   
00303   
00304   
00305   
00306   
00307   fd_mask * maskp = (fd_mask *)(this->handles_.mask_.fds_bits);
00308 
00309   if (this->handle_index_ >= maxhandlep1)
00310     
00311     
00312     return ACE_INVALID_HANDLE;
00313   else
00314     {
00315       ACE_HANDLE result = this->handle_index_;
00316 
00317       
00318       
00319       this->handle_index_++;
00320 #if defined (ACE_TANDEM_NSK_BIT_ORDER)
00321       
00322       this->word_val_ = (this->word_val_ << 1);
00323 #  else
00324       this->word_val_ = (this->word_val_ >> 1) & ACE_MSB_MASK;
00325 #  endif 
00326 
00327       
00328       
00329 
00330       if (this->word_val_ == 0)
00331         {
00332           
00333           
00334           
00335 
00336           for (this->handle_index_ = ACE_MULT_BY_WORDSIZE(++this->word_num_);
00337                this->handle_index_ < maxhandlep1
00338                  && maskp[this->word_num_] == 0;
00339                this->word_num_++)
00340             this->handle_index_ += ACE_Handle_Set::WORDSIZE;
00341 
00342           
00343           
00344           
00345           
00346           
00347           if (this->handle_index_ >= maxhandlep1)
00348             {
00349               this->handle_index_ = maxhandlep1;
00350               return result;
00351             }
00352           else
00353             
00354             this->word_val_ = maskp[this->word_num_];
00355         }
00356 
00357       
00358       
00359       
00360       
00361 
00362 #if defined (ACE_TANDEM_NSK_BIT_ORDER)
00363       
00364       for (;
00365            this->word_val_ > 0;
00366            this->word_val_ = (this->word_val_ << 1))
00367         this->handle_index_++;
00368 #  else
00369       for (;
00370            ACE_BIT_DISABLED (this->word_val_, 1);
00371            this->handle_index_++)
00372         this->word_val_ = (this->word_val_ >> 1) & ACE_MSB_MASK;
00373 #  endif 
00374 
00375       return result;
00376     }
00377 #else 
00378    
00379    register u_long lsb = this->word_val_;
00380 
00381    if (lsb == 0)
00382      {
00383        do
00384          {
00385            
00386            if (++this->word_num_ >= this->word_max_)
00387              return ACE_INVALID_HANDLE;
00388 
00389            lsb = this->handles_.mask_.fds_bits[this->word_num_];
00390          }
00391        while (lsb == 0);
00392 
00393        
00394        this->handle_index_ = ACE_MULT_BY_WORDSIZE (this->word_num_);
00395 
00396        
00397        this->word_val_ = lsb;
00398 
00399        
00400        lsb &= ~(lsb - 1);
00401 
00402        
00403        this->word_val_ ^= lsb;
00404 
00405        
00406        this->oldlsb_ = lsb;
00407 
00408        
00409        while (lsb >>= 1)
00410          this->handle_index_++;
00411      }
00412    else
00413      {
00414         
00415         lsb &= ~(lsb - 1);
00416 
00417         
00418         this->word_val_ ^= lsb;
00419 
00420         register u_long n = lsb - this->oldlsb_;
00421 
00422         
00423         do
00424           {
00425             this->handle_index_++;
00426             n &= n >> 1;
00427           }
00428         while (n != 0);
00429 
00430         this->oldlsb_ = lsb;
00431       }
00432 
00433    return this->handle_index_;
00434 #endif 
00435 }
00436 
00437 ACE_Handle_Set_Iterator::ACE_Handle_Set_Iterator (const ACE_Handle_Set &hs)
00438   : handles_ (hs),
00439 #if !defined (ACE_HAS_BIG_FD_SET) || defined (ACE_WIN32)
00440     handle_index_ (0),
00441     word_num_ (-1)
00442 #elif defined (ACE_HAS_BIG_FD_SET)
00443     oldlsb_ (0),
00444     word_max_ (hs.max_handle_ == ACE_INVALID_HANDLE
00445                ? 0
00446                : ((ACE_DIV_BY_WORDSIZE (hs.max_handle_)) + 1))
00447 #endif 
00448 {
00449   ACE_TRACE ("ACE_Handle_Set_Iterator::ACE_Handle_Set_Iterator");
00450 #if !defined (ACE_WIN32) && !defined (ACE_HAS_BIG_FD_SET)
00451   
00452   ACE_HANDLE maxhandlep1 =
00453     this->handles_.max_handle_ + 1;
00454 
00455   fd_mask *maskp =
00456     (fd_mask *)(this->handles_.mask_.fds_bits);
00457 
00458   
00459   
00460   while (this->handle_index_ < maxhandlep1
00461          && maskp[++this->word_num_] == 0)
00462     this->handle_index_ += ACE_Handle_Set::WORDSIZE;
00463 
00464   
00465   
00466   
00467   
00468   if (this->handle_index_ >= maxhandlep1)
00469     this->handle_index_ = maxhandlep1;
00470   else
00471     
00472     
00473     
00474 #if defined (ACE_TANDEM_NSK_BIT_ORDER)
00475     
00476     for (this->word_val_ = maskp[this->word_num_];
00477          this->word_val_ > 0;
00478          this->word_val_ = (this->word_val_ << 1))
00479       this->handle_index_++;
00480 #  else
00481     for (this->word_val_ = maskp[this->word_num_];
00482          ACE_BIT_DISABLED (this->word_val_, 1)
00483            && this->handle_index_ < maxhandlep1;
00484          this->handle_index_++)
00485       this->word_val_ = (this->word_val_ >> 1) & ACE_MSB_MASK;
00486 #  endif 
00487 #elif !defined (ACE_WIN32) && defined (ACE_HAS_BIG_FD_SET)
00488     if (this->word_max_==0)
00489       {
00490         this->word_num_ = -1;
00491         this->word_val_ = 0;
00492       }
00493     else
00494       {
00495         this->word_num_ =
00496           ACE_DIV_BY_WORDSIZE (this->handles_.min_handle_) - 1;
00497         this->word_val_ = 0;
00498       }
00499 #endif 
00500 }
00501 
00502 
00503 void
00504 ACE_Handle_Set_Iterator::reset_state (void)
00505 {
00506   ACE_TRACE ("ACE_Handle_Set_Iterator::reset_state");
00507 
00508 #if !defined (ACE_HAS_BIG_FD_SET) || defined (ACE_WIN32)
00509   this->handle_index_  = 0;
00510   this->word_num_ = -1;
00511 #elif defined (ACE_HAS_BIG_FD_SET)
00512   this->oldlsb_ = 0;
00513   this->word_max_  =
00514     this->handles_.max_handle_ == ACE_INVALID_HANDLE  ? 0
00515     : ((ACE_DIV_BY_WORDSIZE (this->handles_.max_handle_)) + 1);
00516 #endif 
00517 
00518 #if !defined (ACE_WIN32) && !defined (ACE_HAS_BIG_FD_SET)
00519   
00520   ACE_HANDLE maxhandlep1 =
00521     this->handles_.max_handle_ + 1;
00522 
00523   fd_mask *maskp =
00524     (fd_mask *)(this->handles_.mask_.fds_bits);
00525 
00526   
00527   
00528   while (this->handle_index_ < maxhandlep1
00529          && maskp[++this->word_num_] == 0)
00530     this->handle_index_ += ACE_Handle_Set::WORDSIZE;
00531 
00532   
00533   
00534   
00535   
00536   if (this->handle_index_ >= maxhandlep1)
00537     this->handle_index_ = maxhandlep1;
00538   else
00539     
00540     
00541     
00542 #if defined (ACE_TANDEM_NSK_BIT_ORDER)
00543     
00544     for (this->word_val_ = maskp[this->word_num_];
00545          this->word_val_ > 0;
00546          this->word_val_ = (this->word_val_ << 1))
00547       this->handle_index_++;
00548 #  else
00549     for (this->word_val_ = maskp[this->word_num_];
00550          ACE_BIT_DISABLED (this->word_val_, 1)
00551            && this->handle_index_ < maxhandlep1;
00552          this->handle_index_++)
00553       this->word_val_ = (this->word_val_ >> 1) & ACE_MSB_MASK;
00554 #  endif 
00555 #elif !defined (ACE_WIN32) && defined (ACE_HAS_BIG_FD_SET)
00556     if (this->word_max_==0)
00557       {
00558         this->word_num_ = -1;
00559         this->word_val_ = 0;
00560       }
00561     else
00562       {
00563         this->word_num_ =
00564           ACE_DIV_BY_WORDSIZE (this->handles_.min_handle_) - 1;
00565         this->word_val_ = 0;
00566       }
00567 #endif 
00568 }
00569 
00570 ACE_END_VERSIONED_NAMESPACE_DECL