2 // $Id: Handle_Set.cpp 80826 2008-03-04 14:51:23Z wotte $
4 #include "ace/Handle_Set.h"
6 #if !defined (__ACE_INLINE__)
7 #include "ace/Handle_Set.inl"
8 #endif /* __ACE_INLINE__ */
10 #include "ace/OS_NS_string.h"
12 ACE_RCSID(ace
, Handle_Set
, "$Id: Handle_Set.cpp 80826 2008-03-04 14:51:23Z wotte $")
14 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
16 ACE_ALLOC_HOOK_DEFINE(ACE_Handle_Set
)
18 // ACE_MSB_MASK is only used here.
19 // This needs to go here to avoid overflow problems on some compilers.
20 #if defined (ACE_WIN32)
21 // Does ACE_WIN32 have an fd_mask?
22 # define ACE_MSB_MASK (~(1 << (NFDBITS - 1)))
23 #else /* ! ACE_WIN32 */
24 # define ACE_MSB_MASK (~((fd_mask) 1 << (NFDBITS - 1)))
25 #endif /* ! ACE_WIN32 */
27 #if defined (__BORLANDC__) && !defined (ACE_WIN32)
28 // The Borland C++ compiler on Linux also doesn't have fds_bits, but has __fds_bits.
29 #define fds_bits __fds_bits
32 #if defined (linux) && __GLIBC__ > 1 && __GLIBC_MINOR__ >= 1 && !defined (_XOPEN_SOURCE)
33 // XPG4.2 requires the fds_bits member name, so it is not enabled by
34 // default on Linux/glibc-2.1.x systems. Instead use "__fds_bits."
35 // Ugly, but "what are you going to do?" 8-)
36 #define fds_bits __fds_bits
37 #endif /* linux && __GLIBC__ > 1 && __GLIBC_MINOR__ >= 1 && !_XOPEN_SOURCE */
40 ACE_Handle_Set::dump (void) const
42 #if defined (ACE_HAS_DUMP)
43 ACE_TRACE ("ACE_Handle_Set::dump");
45 ACE_DEBUG ((LM_DEBUG
, ACE_BEGIN_DUMP
, this));
47 ACE_DEBUG ((LM_DEBUG
, ACE_TEXT ("\nsize_ = %d"), this->size_
));
48 ACE_DEBUG ((LM_DEBUG
, ACE_TEXT ("\nmax_handle_ = %d"), this->max_handle_
));
49 ACE_DEBUG ((LM_DEBUG
, ACE_TEXT ("\n[ ")));
51 #if defined (ACE_WIN32)
52 for (size_t i
= 0; i
< (size_t) this->mask_
.fd_count
+ 1; i
++)
53 ACE_DEBUG ((LM_DEBUG
, ACE_TEXT (" %x "), this->mask_
.fd_array
[i
]));
54 #else /* !ACE_WIN32 */
55 for (ACE_HANDLE i
= 0; i
< this->max_handle_
+ 1; i
++)
57 ACE_DEBUG ((LM_DEBUG
, ACE_TEXT (" %d "), i
));
58 #endif /* ACE_WIN32 */
60 ACE_DEBUG ((LM_DEBUG
, ACE_TEXT (" ]\n")));
61 ACE_DEBUG ((LM_DEBUG
, ACE_END_DUMP
));
62 #endif /* ACE_HAS_DUMP */
65 // Table that maps bytes to counts of the enabled bits in each value
70 // because there are no bits enabled for the value 0.
74 // because there are 2 bits enabled in the value 5, i.e., it's
77 const char ACE_Handle_Set::nbits_
[256] =
79 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4,
80 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
81 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
82 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
83 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
84 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
85 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
86 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
87 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
88 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
89 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
90 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
91 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
92 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
93 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
94 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8};
96 // Constructor, initializes the bitmask to all 0s.
98 ACE_Handle_Set::ACE_Handle_Set (void)
100 ACE_TRACE ("ACE_Handle_Set::ACE_Handle_Set");
104 ACE_Handle_Set::ACE_Handle_Set (const fd_set
&fd_mask
)
106 ACE_TRACE ("ACE_Handle_Set::ACE_Handle_Set");
108 ACE_OS::memcpy ((void *) &this->mask_
,
111 #if !defined (ACE_WIN32)
112 this->sync (ACE_Handle_Set::MAXSIZE
);
113 #if defined (ACE_HAS_BIG_FD_SET)
114 this->min_handle_
= 0;
115 #endif /* ACE_HAS_BIG_FD_SET */
116 #endif /* !ACE_WIN32 */
119 // Counts the number of bits enabled in N. Uses a table lookup to
120 // speed up the count.
123 ACE_Handle_Set::count_bits (u_long n
)
126 ACE_TRACE ("ACE_Handle_Set::count_bits");
127 #if defined (ACE_HAS_HANDLE_SET_OPTIMIZED_FOR_SELECT)
128 register int rval
= 0;
130 // Count the number of enabled bits in <n>. This algorithm is very
131 // fast, i.e., O(enabled bits in n).
133 for (register u_long m
= n
;
140 return (ACE_Handle_Set::nbits_
[n
& 0xff]
141 + ACE_Handle_Set::nbits_
[(n
>> 8) & 0xff]
142 + ACE_Handle_Set::nbits_
[(n
>> 16) & 0xff]
143 + ACE_Handle_Set::nbits_
[(n
>> 24) & 0xff]);
144 #endif /* ACE_HAS_HANDLE_SET_OPTIMIZED_FOR_SELECT */
147 #if defined (ACE_HAS_BIG_FD_SET)
148 // Find the bit position counting from right to left worst case
152 ACE_Handle_Set::bitpos (u_long bit
)
155 register u_long n
= bit
- 1;
157 // This is a fast count method when have the most significative bit.
165 // Is greater than 15?
172 // Count number remaining bits.
180 #endif /* ACE_HAS_BIG_FD_SET */
182 // Synchronize the underlying FD_SET with the MAX_FD and the SIZE.
184 #if defined (ACE_USE_SHIFT_FOR_EFFICIENCY)
185 // These don't work because shifting right 3 bits is not the same as
186 // dividing by 3, e.g., dividing by 8 requires shifting right 3 bits.
187 // In order to do the shift, we need to calculate the number of bits
189 #define ACE_DIV_BY_WORDSIZE(x) ((x) >> ((int) ACE_Handle_Set::WORDSIZE))
190 #define ACE_MULT_BY_WORDSIZE(x) ((x) << ((int) ACE_Handle_Set::WORDSIZE))
192 #define ACE_DIV_BY_WORDSIZE(x) ((x) / ((int) ACE_Handle_Set::WORDSIZE))
193 #define ACE_MULT_BY_WORDSIZE(x) ((x) * ((int) ACE_Handle_Set::WORDSIZE))
194 #endif /* ACE_USE_SHIFT_FOR_EFFICIENCY */
197 ACE_Handle_Set::sync (ACE_HANDLE max
)
199 ACE_TRACE ("ACE_Handle_Set::sync");
200 #if !defined (ACE_WIN32)
201 fd_mask
*maskp
= (fd_mask
*)(this->mask_
.fds_bits
);
204 for (int i
= ACE_DIV_BY_WORDSIZE (max
- 1);
207 this->size_
+= ACE_Handle_Set::count_bits (maskp
[i
]);
211 ACE_UNUSED_ARG (max
);
212 #endif /* !ACE_WIN32 */
215 // Resets the MAX_FD after a clear of the original MAX_FD.
218 ACE_Handle_Set::set_max (ACE_HANDLE current_max
)
220 ACE_TRACE ("ACE_Handle_Set::set_max");
221 #if !defined(ACE_WIN32)
222 fd_mask
* maskp
= (fd_mask
*)(this->mask_
.fds_bits
);
224 if (this->size_
== 0)
225 this->max_handle_
= ACE_INVALID_HANDLE
;
230 for (i
= ACE_DIV_BY_WORDSIZE (current_max
- 1);
234 #if defined (ACE_TANDEM_NSK_BIT_ORDER)
235 // bits are in reverse order, MSB (sign bit) = bit 0.
236 this->max_handle_
= ACE_MULT_BY_WORDSIZE (i
);
237 for (fd_mask val
= maskp
[i
];
238 (val
& ACE_MSB_MASK
) != 0;
241 #elif 1 /* !defined(ACE_HAS_BIG_FD_SET) */
242 this->max_handle_
= ACE_MULT_BY_WORDSIZE (i
);
243 for (fd_mask val
= maskp
[i
];
244 (val
& ~1) != 0; // This obscure code is needed since "bit 0" is in location 1...
245 val
= (val
>> 1) & ACE_MSB_MASK
)
248 register u_long val
= this->mask_
.fds_bits
[i
];
249 this->max_handle_
= ACE_MULT_BY_WORDSIZE (i
)
250 + ACE_Handle_Set::bitpos(val
& ~(val
- 1));
254 // Do some sanity checking...
255 if (this->max_handle_
>= ACE_Handle_Set::MAXSIZE
)
256 this->max_handle_
= ACE_Handle_Set::MAXSIZE
- 1;
258 ACE_UNUSED_ARG (current_max
);
259 #endif /* !ACE_WIN32 */
262 ACE_ALLOC_HOOK_DEFINE(ACE_Handle_Set_Iterator
)
265 ACE_Handle_Set_Iterator::dump (void) const
267 #if defined (ACE_HAS_DUMP)
268 ACE_TRACE ("ACE_Handle_Set_Iterator::dump");
270 ACE_DEBUG ((LM_DEBUG
, ACE_BEGIN_DUMP
, this));
271 #if defined(ACE_WIN32) || !defined(ACE_HAS_BIG_FD_SET)
272 ACE_DEBUG ((LM_DEBUG
, ACE_TEXT ("\nhandle_index_ = %d"), this->handle_index_
));
273 #elif defined(ACE_HAS_BIG_FD_SET)
274 ACE_DEBUG ((LM_DEBUG
, ACE_TEXT ("\nword_max_ = %d"), this->word_max_
));
275 ACE_DEBUG ((LM_DEBUG
, ACE_TEXT ("\nword_val_ = %d"), this->word_val_
));
277 ACE_DEBUG ((LM_DEBUG
, ACE_TEXT ("\nword_num_ = %d"), this->word_num_
));
278 ACE_DEBUG ((LM_DEBUG
, ACE_END_DUMP
));
279 #endif /* ACE_HAS_DUMP */
283 ACE_Handle_Set_Iterator::operator () (void)
285 ACE_TRACE ("ACE_Handle_Set_Iterator::operator");
286 #if defined (ACE_WIN32)
287 if (this->handle_index_
< this->handles_
.mask_
.fd_count
)
288 // Return the handle and advance the iterator.
289 return (ACE_HANDLE
) this->handles_
.mask_
.fd_array
[this->handle_index_
++];
291 return ACE_INVALID_HANDLE
;
293 #elif !defined (ACE_HAS_BIG_FD_SET) /* !ACE_WIN32 */
294 // No sense searching further than the max_handle_ + 1;
295 ACE_HANDLE maxhandlep1
= this->handles_
.max_handle_
+ 1;
297 // HP-UX 11 plays some games with the fd_mask type - fd_mask is
298 // defined as an int_32t, but the fds_bits is an array of longs.
299 // This makes plainly indexing through the array by hand tricky,
300 // since the FD_* macros treat the array as int32_t. So the bits
301 // are in the right place for int32_t, even though the array is
302 // long. This, they say, is to preserve the same in-memory layout
303 // for 32-bit and 64-bit processes. So, we play the same game as
304 // the FD_* macros to get the bits right. On all other systems,
305 // this amounts to practically a NOP, since this is what would have
306 // been done anyway, without all this type jazz.
307 fd_mask
* maskp
= (fd_mask
*)(this->handles_
.mask_
.fds_bits
);
309 if (this->handle_index_
>= maxhandlep1
)
310 // We've seen all the handles we're interested in seeing for this
312 return ACE_INVALID_HANDLE
;
315 ACE_HANDLE result
= this->handle_index_
;
317 // Increment the iterator and advance to the next bit in this
319 this->handle_index_
++;
320 #if defined (ACE_TANDEM_NSK_BIT_ORDER)
321 // bits are in reverse order, MSB (sign bit) = bit 0.
322 this->word_val_
= (this->word_val_
<< 1);
324 this->word_val_
= (this->word_val_
>> 1) & ACE_MSB_MASK
;
325 # endif /* ACE_TANDEM_NSK_BIT_ORDER */
327 // If we've examined all the bits in this word, we'll go onto
330 if (this->word_val_
== 0)
332 // Start the handle_index_ at the beginning of the next word
333 // and then loop until we've found the first non-zero bit or
334 // we run past the <maxhandlep1> of the bitset.
336 for (this->handle_index_
= ACE_MULT_BY_WORDSIZE(++this->word_num_
);
337 this->handle_index_
< maxhandlep1
338 && maskp
[this->word_num_
] == 0;
340 this->handle_index_
+= ACE_Handle_Set::WORDSIZE
;
342 // If the bit index becomes >= the maxhandlep1 that means
343 // there weren't any more bits set that we want to consider.
344 // Therefore, we'll just store the maxhandlep1, which will
345 // cause <operator()> to return <ACE_INVALID_HANDLE>
346 // immediately next time it's called.
347 if (this->handle_index_
>= maxhandlep1
)
349 this->handle_index_
= maxhandlep1
;
353 // Load the bits of the next word.
354 this->word_val_
= maskp
[this->word_num_
];
357 // Loop until we get <word_val_> to have its least significant
358 // bit enabled, keeping track of which <handle_index> this
359 // represents (this information is used by subsequent calls to
362 #if defined (ACE_TANDEM_NSK_BIT_ORDER)
363 // bits are in reverse order, MSB (sign bit) = bit 0.
366 this->word_val_
= (this->word_val_
<< 1))
367 this->handle_index_
++;
370 ACE_BIT_DISABLED (this->word_val_
, 1);
371 this->handle_index_
++)
372 this->word_val_
= (this->word_val_
>> 1) & ACE_MSB_MASK
;
373 # endif /* ACE_TANDEM_NSK_BIT_ORDER */
377 #else /* !ACE_HAS_BIG_FD_SET */
378 // Find the first word in fds_bits with bit on
379 register u_long lsb
= this->word_val_
;
385 // We have exceeded the word count in Handle_Set?
386 if (++this->word_num_
>= this->word_max_
)
387 return ACE_INVALID_HANDLE
;
389 lsb
= this->handles_
.mask_
.fds_bits
[this->word_num_
];
393 // Set index to word boundary.
394 this->handle_index_
= ACE_MULT_BY_WORDSIZE (this->word_num_
);
397 this->word_val_
= lsb
;
399 // Find the least significative bit.
402 // Remove least significative bit.
403 this->word_val_
^= lsb
;
405 // Save to calculate bit distance.
408 // Move index to least significative bit.
410 this->handle_index_
++;
414 // Find the least significative bit.
417 // Remove least significative bit.
418 this->word_val_
^= lsb
;
420 register u_long n
= lsb
- this->oldlsb_
;
422 // Move index to bit distance between new lsb and old lsb.
425 this->handle_index_
++;
433 return this->handle_index_
;
434 #endif /* ACE_WIN32 */
437 ACE_Handle_Set_Iterator::ACE_Handle_Set_Iterator (const ACE_Handle_Set
&hs
)
439 #if !defined (ACE_HAS_BIG_FD_SET) || defined (ACE_WIN32)
442 #elif defined (ACE_HAS_BIG_FD_SET)
444 word_max_ (hs
.max_handle_
== ACE_INVALID_HANDLE
446 : ((ACE_DIV_BY_WORDSIZE (hs
.max_handle_
)) + 1))
447 #endif /* ACE_HAS_BIG_FD_SET */
449 ACE_TRACE ("ACE_Handle_Set_Iterator::ACE_Handle_Set_Iterator");
450 #if !defined (ACE_WIN32) && !defined (ACE_HAS_BIG_FD_SET)
451 // No sense searching further than the max_handle_ + 1;
452 ACE_HANDLE maxhandlep1
=
453 this->handles_
.max_handle_
+ 1;
456 (fd_mask
*)(this->handles_
.mask_
.fds_bits
);
458 // Loop until we've found the first non-zero bit or we run past the
459 // <maxhandlep1> of the bitset.
460 while (this->handle_index_
< maxhandlep1
461 && maskp
[++this->word_num_
] == 0)
462 this->handle_index_
+= ACE_Handle_Set::WORDSIZE
;
464 // If the bit index becomes >= the maxhandlep1 that means there
465 // weren't any bits set. Therefore, we'll just store the
466 // maxhandlep1, which will cause <operator()> to return
467 // <ACE_INVALID_HANDLE> immediately.
468 if (this->handle_index_
>= maxhandlep1
)
469 this->handle_index_
= maxhandlep1
;
471 // Loop until we get <word_val_> to have its least significant bit
472 // enabled, keeping track of which <handle_index> this represents
473 // (this information is used by <operator()>).
474 #if defined (ACE_TANDEM_NSK_BIT_ORDER)
475 // bits are in reverse order, MSB (sign bit) = bit 0.
476 for (this->word_val_
= maskp
[this->word_num_
];
478 this->word_val_
= (this->word_val_
<< 1))
479 this->handle_index_
++;
481 for (this->word_val_
= maskp
[this->word_num_
];
482 ACE_BIT_DISABLED (this->word_val_
, 1)
483 && this->handle_index_
< maxhandlep1
;
484 this->handle_index_
++)
485 this->word_val_
= (this->word_val_
>> 1) & ACE_MSB_MASK
;
486 # endif /* ACE_TANDEM_NSK_BIT_ORDER */
487 #elif !defined (ACE_WIN32) && defined (ACE_HAS_BIG_FD_SET)
488 if (this->word_max_
==0)
490 this->word_num_
= -1;
496 ACE_DIV_BY_WORDSIZE (this->handles_
.min_handle_
) - 1;
499 #endif /* !ACE_WIN32 && !ACE_HAS_BIG_FD_SET */
504 ACE_Handle_Set_Iterator::reset_state (void)
506 ACE_TRACE ("ACE_Handle_Set_Iterator::reset_state");
508 #if !defined (ACE_HAS_BIG_FD_SET) || defined (ACE_WIN32)
509 this->handle_index_
= 0;
510 this->word_num_
= -1;
511 #elif defined (ACE_HAS_BIG_FD_SET)
514 this->handles_
.max_handle_
== ACE_INVALID_HANDLE
? 0
515 : ((ACE_DIV_BY_WORDSIZE (this->handles_
.max_handle_
)) + 1);
516 #endif /* ACE_HAS_BIG_FD_SET */
518 #if !defined (ACE_WIN32) && !defined (ACE_HAS_BIG_FD_SET)
519 // No sense searching further than the max_handle_ + 1;
520 ACE_HANDLE maxhandlep1
=
521 this->handles_
.max_handle_
+ 1;
524 (fd_mask
*)(this->handles_
.mask_
.fds_bits
);
526 // Loop until we've found the first non-zero bit or we run past the
527 // <maxhandlep1> of the bitset.
528 while (this->handle_index_
< maxhandlep1
529 && maskp
[++this->word_num_
] == 0)
530 this->handle_index_
+= ACE_Handle_Set::WORDSIZE
;
532 // If the bit index becomes >= the maxhandlep1 that means there
533 // weren't any bits set. Therefore, we'll just store the
534 // maxhandlep1, which will cause <operator()> to return
535 // <ACE_INVALID_HANDLE> immediately.
536 if (this->handle_index_
>= maxhandlep1
)
537 this->handle_index_
= maxhandlep1
;
539 // Loop until we get <word_val_> to have its least significant bit
540 // enabled, keeping track of which <handle_index> this represents
541 // (this information is used by <operator()>).
542 #if defined (ACE_TANDEM_NSK_BIT_ORDER)
543 // bits are in reverse order, MSB (sign bit) = bit 0.
544 for (this->word_val_
= maskp
[this->word_num_
];
546 this->word_val_
= (this->word_val_
<< 1))
547 this->handle_index_
++;
549 for (this->word_val_
= maskp
[this->word_num_
];
550 ACE_BIT_DISABLED (this->word_val_
, 1)
551 && this->handle_index_
< maxhandlep1
;
552 this->handle_index_
++)
553 this->word_val_
= (this->word_val_
>> 1) & ACE_MSB_MASK
;
554 # endif /* ACE_TANDEM_NSK_BIT_ORDER */
555 #elif !defined (ACE_WIN32) && defined (ACE_HAS_BIG_FD_SET)
556 if (this->word_max_
==0)
558 this->word_num_
= -1;
564 ACE_DIV_BY_WORDSIZE (this->handles_
.min_handle_
) - 1;
567 #endif /* !ACE_WIN32 && !ACE_HAS_BIG_FD_SET */
570 ACE_END_VERSIONED_NAMESPACE_DECL