cdev-1.7.2n
This commit is contained in:
304
extensions/cdevGenericServer/cdevReactor/cdevHandleSet.cc
Normal file
304
extensions/cdevGenericServer/cdevReactor/cdevHandleSet.cc
Normal file
@@ -0,0 +1,304 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 1994,1995 Southeastern Universities Research Association,
|
||||
// Continuous Electron Beam Accelerator Facility
|
||||
//
|
||||
// This software was developed under a United States Government license
|
||||
// described in the NOTICE file included as part of this distribution.
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Description:
|
||||
// FD_Set Wrapper Based on ACE
|
||||
//
|
||||
|
||||
#include "cdevHandleSet.h"
|
||||
|
||||
#ifndef __VMS
|
||||
#ifndef __linux
|
||||
extern "C" bzero (char *, int);
|
||||
#endif
|
||||
#else
|
||||
extern "C" bzero (char *, unsigned int);
|
||||
#endif
|
||||
|
||||
#if defined(__VMS) && defined(_TGV_MULTINET)
|
||||
// *********************************************************************
|
||||
// * Unfortunately when you use TGV Multinet, the bit offsets in the
|
||||
// * file * descriptor bitmasks used by select() cannot be found by
|
||||
// * simply using the value of the file descriptor. Fortunately, there
|
||||
// * is a simple relationship between the file descriptor value and the
|
||||
// * desired bit offset.
|
||||
// * (These macros are required because this file accesses the file
|
||||
// * descriptor bitmasks directly, without using the FD_SET(), FD_CLR(),
|
||||
// * FD_ISSSET() macros).
|
||||
// *********************************************************************
|
||||
#define FD_TO_BIT_OFFSET( fd ) ((fd)/CHANNELSIZE)
|
||||
#define FD_FROM_BIT_OFFSET( ibit ) ((ibit)*CHANNELSIZE)
|
||||
#else
|
||||
// *********************************************************************
|
||||
// * Under most operating systems the file descriptor value and the
|
||||
// * associated bit offset are one and the same.
|
||||
// *********************************************************************
|
||||
#define FD_TO_BIT_OFFSET( fd ) (fd)
|
||||
#define FD_FROM_BIT_OFFSET( ibit ) (ibit)
|
||||
#endif
|
||||
|
||||
#ifdef CDEV_HAS_UNDERSCORE_FDBITS
|
||||
#define fds_bits __fds_bits
|
||||
#endif
|
||||
|
||||
inline int BIT_ENABLED (unsigned long word, int bit = 1) { return (word & bit) != 0; }
|
||||
inline int BIT_DISABLED (unsigned long word, int bit = 1) { return (word & bit) == 0; }
|
||||
inline void SET_BIT (unsigned long &word, int bit) { word |= bit; }
|
||||
inline void CLR_BIT (unsigned long &word, int bit) { word &= ~bit; }
|
||||
|
||||
const char cdevHandleSet::nbits_[256] =
|
||||
{
|
||||
0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4,
|
||||
1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
|
||||
1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
|
||||
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
|
||||
1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
|
||||
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
|
||||
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
|
||||
3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
|
||||
1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
|
||||
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
|
||||
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
|
||||
3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
|
||||
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
|
||||
3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
|
||||
3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
|
||||
4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8,
|
||||
};
|
||||
|
||||
// *****************************************************************************
|
||||
// * Counts the number of bits enabled in N. Uses a table lookup to speed up
|
||||
// * the count.
|
||||
// *****************************************************************************
|
||||
|
||||
int cdevHandleSet::count_bits (unsigned long n) const
|
||||
{
|
||||
return (cdevHandleSet::nbits_[n & 0xff] + cdevHandleSet::nbits_[(n >> 8) & 0xff] +
|
||||
cdevHandleSet::nbits_[(n >> 16) & 0xff] + cdevHandleSet::nbits_[n >> 24]);
|
||||
}
|
||||
|
||||
void cdevHandleSetIterator::operator++ (void)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
this->index_++;
|
||||
#else
|
||||
this->val_ = (this->val_ >> 1) & cdevHandleSet::MSB_MASK;
|
||||
this->num_++;
|
||||
|
||||
if (this->val_ == 0)
|
||||
{
|
||||
for (this->index_++;
|
||||
this->index_ < cdevHandleSet::NUM_WORDS && fds_.mask_.fds_bits[this->index_] == 0;
|
||||
this->index_++);
|
||||
|
||||
if (this->index_ == cdevHandleSet::NUM_WORDS)
|
||||
{
|
||||
this->num_ = fds_.max_handle_ + 1;
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
this->val_ = fds_.mask_.fds_bits[this->index_];
|
||||
this->num_ = this->index_ * cdevHandleSet::WORD_SIZE;
|
||||
}
|
||||
}
|
||||
|
||||
for (; BIT_DISABLED (this->val_); this->num_++)
|
||||
this->val_ = (this->val_ >> 1) & cdevHandleSet::MSB_MASK;
|
||||
#endif
|
||||
}
|
||||
|
||||
cdevHandleSetIterator::cdevHandleSetIterator (cdevHandleSet &f)
|
||||
: fds_ (f), index_ (0), num_ (f.size_ == 0 ? f.max_handle_ + 1 : 0)
|
||||
{
|
||||
#ifndef _WIN32
|
||||
for (; fds_.mask_.fds_bits[this->index_] == 0; this->index_++)
|
||||
this->num_ += cdevHandleSet::WORD_SIZE;
|
||||
|
||||
for (this->val_ = this->fds_.mask_.fds_bits[this->index_];
|
||||
(BIT_DISABLED (this->val_)) && this->num_ < cdevHandleSet::MAX_SIZE;
|
||||
this->num_++)
|
||||
this->val_ = (this->val_ >> 1) & cdevHandleSet::MSB_MASK;
|
||||
#endif
|
||||
}
|
||||
|
||||
// *****************************************************************************
|
||||
// * Synchronize the underlying FD_SET with the MAX_FD and the SIZE.
|
||||
// *****************************************************************************
|
||||
void cdevHandleSet::sync (int max)
|
||||
{
|
||||
#ifndef _WIN32
|
||||
this->size_ = 0;
|
||||
|
||||
for (int i = max / cdevHandleSet::WORD_SIZE; i >= 0; i--)
|
||||
this->size_ += count_bits (this->mask_.fds_bits[i]);
|
||||
|
||||
this->set_max (max);
|
||||
#endif
|
||||
}
|
||||
|
||||
// *****************************************************************************
|
||||
// * Resets the MAX_FD after a clear of the original MAX_FD.
|
||||
// *****************************************************************************
|
||||
void cdevHandleSet::set_max (int current_max)
|
||||
{
|
||||
#ifndef _WIN32
|
||||
int i = 0;
|
||||
|
||||
if (this->size_ == 0)
|
||||
this->max_handle_ = -1;
|
||||
else
|
||||
{
|
||||
for (i = current_max / cdevHandleSet::WORD_SIZE;
|
||||
this->mask_.fds_bits[i] == 0;
|
||||
i--)
|
||||
;
|
||||
|
||||
this->max_handle_ = i * cdevHandleSet::WORD_SIZE;
|
||||
for (fd_mask val = this->mask_.fds_bits[i];
|
||||
(val & ~1) != 0;
|
||||
val = (val >> 1) & cdevHandleSet::MSB_MASK)
|
||||
this->max_handle_++;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// *****************************************************************************
|
||||
// * Debugging method that prints out the underlying mask.
|
||||
// *****************************************************************************
|
||||
int cdevHandleSet::asciiDump (FILE * fp)
|
||||
{
|
||||
fprintf(fp, "[ ");
|
||||
for (int i = 0; i < this->max_handle_ + 1; i++)
|
||||
if (this->is_set (i))
|
||||
fprintf(fp," %d ", i);
|
||||
|
||||
fprintf(fp, " ]");
|
||||
return this->size_;
|
||||
}
|
||||
|
||||
void cdevHandleSet::reset (void)
|
||||
{
|
||||
this->max_handle_ = -1;
|
||||
this->size_ = 0;
|
||||
FD_ZERO (&this->mask_);
|
||||
}
|
||||
|
||||
// *****************************************************************************
|
||||
// * Constructor, initializes the bitmask to all 0s.
|
||||
// *****************************************************************************
|
||||
cdevHandleSet::cdevHandleSet (void)
|
||||
{
|
||||
this->reset ();
|
||||
}
|
||||
|
||||
cdevHandleSet::cdevHandleSet (const fd_set &fd_mask): size_ (0)
|
||||
{
|
||||
memcpy ((void *) &this->mask_, (void *) &fd_mask, sizeof this->mask_);
|
||||
// sync is empty for WIN32
|
||||
this->sync (FD_SETSIZE);
|
||||
}
|
||||
|
||||
// *****************************************************************************
|
||||
// * Returns the number of the large bit.
|
||||
// *****************************************************************************
|
||||
int cdevHandleSet::max_set (void) const
|
||||
{
|
||||
return this->max_handle_;
|
||||
}
|
||||
|
||||
// *****************************************************************************
|
||||
// * Checks whether FD is enabled.
|
||||
// *****************************************************************************
|
||||
int cdevHandleSet::is_set (int fd) const
|
||||
{
|
||||
#ifdef _WIN32
|
||||
return FD_ISSET ((SOCKET)fd, &this->mask_);
|
||||
#else
|
||||
return FD_ISSET (fd, &this->mask_);
|
||||
#endif
|
||||
}
|
||||
|
||||
// *****************************************************************************
|
||||
// * Enables the FD.
|
||||
// *****************************************************************************
|
||||
void cdevHandleSet::set_bit (int fd)
|
||||
{
|
||||
if (!this->is_set (fd))
|
||||
{
|
||||
#ifdef _WIN32
|
||||
FD_SET ((SOCKET)fd, &this->mask_);
|
||||
#else
|
||||
FD_SET (fd, &this->mask_);
|
||||
this->size_++;
|
||||
// *****************************************************
|
||||
// * again VMS system has different idea
|
||||
// *****************************************************
|
||||
#if defined(__VMS) && defined(_TGV_MULTINET)
|
||||
if (FD_TO_BIT_OFFSET(fd) > this->max_handle_)
|
||||
this->max_handle_ = FD_TO_BIT_OFFSET(fd);
|
||||
#else
|
||||
if (fd > this->max_handle_)
|
||||
this->max_handle_ = fd;
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
// *****************************************************************************
|
||||
// * Disables the FD.
|
||||
// *****************************************************************************
|
||||
void cdevHandleSet::clr_bit (int fd)
|
||||
{
|
||||
if (this->is_set (fd))
|
||||
{
|
||||
#ifdef _WIN32
|
||||
FD_CLR ((SOCKET)fd, &this->mask_);
|
||||
#else
|
||||
FD_CLR (fd, &this->mask_);
|
||||
this->size_--;
|
||||
|
||||
#if defined(__VMS) && defined(_TGV_MULTINET)
|
||||
if (FD_TO_BIT_OFFSET(fd) == this->max_handle_)
|
||||
this->set_max (this->max_handle_);
|
||||
#else
|
||||
if (fd == this->max_handle_)
|
||||
this->set_max (this->max_handle_);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
// *****************************************************************************
|
||||
// * Returns a count of the number of enabled bits.
|
||||
// *****************************************************************************
|
||||
int cdevHandleSet::num_set (void) const
|
||||
{
|
||||
#ifdef _WIN32
|
||||
return this->mask_.fd_count;
|
||||
#else
|
||||
return this->size_;
|
||||
#endif
|
||||
}
|
||||
|
||||
int cdevHandleSetIterator::operator () (void)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
return this->index_ < this->fds_.mask_.fd_count
|
||||
? fds_.mask_.fd_array[this->index_] : -1;
|
||||
#else
|
||||
#if defined(__VMS) && defined(_TGV_MULTINET)
|
||||
return FD_FROM_BIT_OFFSET(this->num_ <= this->fds_.max_handle_
|
||||
? this->num_ :-1);
|
||||
#else
|
||||
return this->num_ <= this->fds_.max_handle_
|
||||
? this->num_ : -1;
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
Reference in New Issue
Block a user