Add a simple FD_Set wrapper/helper class.

This commit is contained in:
Jon Siwek 2014-09-09 16:28:04 -05:00
parent cf66bd8b69
commit 59c54a0fc6
16 changed files with 149 additions and 90 deletions

83
src/iosource/FD_Set.h Normal file
View file

@ -0,0 +1,83 @@
#ifndef BRO_FD_SET_H
#define BRO_FD_SET_H
#include <set>
#include <sys/select.h>
namespace iosource {
/**
* A container holding a set of file descriptors.
*/
class FD_Set {
public:
/**
* Constructor. The set is initially empty.
*/
FD_Set()
: max(-1), fds()
{ }
/**
* Insert a file descriptor in to the set.
* @param fd the fd to insert in the set.
* @return false if fd was already in the set, else true.
*/
bool Insert(int fd)
{
if ( max < fd ) max = fd;
return fds.insert(fd).second;
}
/**
* Inserts all the file descriptors from another set in to this one.
* @param other a file descriptor set to merge in to this one.
*/
void Aggregate(const FD_Set& other)
{
for ( std::set<int>::const_iterator it = other.fds.begin();
it != other.fds.end(); ++it )
Insert(*it);
}
/**
* Empties the set.
*/
void Clear()
{ max = -1; fds.clear(); }
/**
* Insert file descriptors in to a fd_set for use with select().
* @return the greatest file descriptor inserted.
*/
int Set(fd_set* set) const
{
for ( std::set<int>::const_iterator it = fds.begin(); it != fds.end();
++it )
FD_SET(*it, set);
return max;
}
/**
* @return Whether a file descriptor belonging to this set is within the
* fd_set arugment.
*/
bool Ready(fd_set* set) const
{
for ( std::set<int>::const_iterator it = fds.begin(); it != fds.end();
++it )
if ( FD_ISSET(*it, set) )
return true;
return false;
}
private:
int max;
std::set<int> fds;
};
} // namespace bro
#endif // BRO_FD_SET_H

View file

@ -8,8 +8,7 @@ extern "C" {
}
#include <string>
#include <vector>
#include "FD_Set.h"
#include "Timer.h"
namespace iosource {
@ -62,8 +61,7 @@ public:
*
* @param except Pointer to container where to insert a except descriptor.
*/
virtual void GetFds(std::vector<int>* read, std::vector<int>* write,
std::vector<int>* except) = 0;
virtual void GetFds(FD_Set* read, FD_Set* write, FD_Set* except) = 0;
/**
* Returns the timestamp (in \a global network time) associated with

View file

@ -44,15 +44,6 @@ void Manager::RemoveAll()
dont_counts = sources.size();
}
static void fd_vector_set(const std::vector<int>& fds, fd_set* set, int* max)
{
for ( size_t i = 0; i < fds.size(); ++i )
{
FD_SET(fds[i], set);
*max = ::max(fds[i], *max);
}
}
IOSource* Manager::FindSoonest(double* ts)
{
// Remove sources which have gone dry. For simplicity, we only
@ -124,14 +115,9 @@ IOSource* Manager::FindSoonest(double* ts)
// be ready.
continue;
src->fd_read.clear();
src->fd_write.clear();
src->fd_except.clear();
src->Clear();
src->src->GetFds(&src->fd_read, &src->fd_write, &src->fd_except);
fd_vector_set(src->fd_read, &fd_read, &maxx);
fd_vector_set(src->fd_write, &fd_write, &maxx);
fd_vector_set(src->fd_except, &fd_except, &maxx);
src->SetFds(&fd_read, &fd_write, &fd_except, &maxx);
}
// We can't block indefinitely even when all sources are dry:
@ -316,21 +302,10 @@ PktDumper* Manager::OpenPktDumper(const string& path, bool append)
return pd;
}
static bool fd_vector_ready(const std::vector<int>& fds, fd_set* set)
void Manager::Source::SetFds(fd_set* read, fd_set* write, fd_set* except,
int* maxx) const
{
for ( size_t i = 0; i < fds.size(); ++i )
if ( FD_ISSET(fds[i], set) )
return true;
return false;
}
bool Manager::Source::Ready(fd_set* read, fd_set* write, fd_set* except) const
{
if ( fd_vector_ready(fd_read, read) ||
fd_vector_ready(fd_write, write) ||
fd_vector_ready(fd_except, except) )
return true;
return false;
*maxx = std::max(*maxx, fd_read.Set(read));
*maxx = std::max(*maxx, fd_write.Set(write));
*maxx = std::max(*maxx, fd_except.Set(except));
}

View file

@ -5,8 +5,7 @@
#include <string>
#include <list>
#include <vector>
#include <sys/select.h>
#include "iosource/FD_Set.h"
namespace iosource {
@ -115,11 +114,19 @@ private:
struct Source {
IOSource* src;
std::vector<int> fd_read;
std::vector<int> fd_write;
std::vector<int> fd_except;
FD_Set fd_read;
FD_Set fd_write;
FD_Set fd_except;
bool Ready(fd_set* read, fd_set* write, fd_set* except) const;
bool Ready(fd_set* read, fd_set* write, fd_set* except) const
{ return fd_read.Ready(read) || fd_write.Ready(write) ||
fd_except.Ready(except); }
void SetFds(fd_set* read, fd_set* write, fd_set* except,
int* maxx) const;
void Clear()
{ fd_read.Clear(); fd_write.Clear(); fd_except.Clear(); }
};
typedef std::list<Source*> SourceList;

View file

@ -218,8 +218,8 @@ void PktSrc::Done()
Close();
}
void PktSrc::GetFds(std::vector<int>* read, std::vector<int>* write,
std::vector<int>* except)
void PktSrc::GetFds(iosource::FD_Set* read, iosource::FD_Set* write,
iosource::FD_Set* except)
{
if ( pseudo_realtime )
{
@ -230,7 +230,7 @@ void PktSrc::GetFds(std::vector<int>* read, std::vector<int>* write,
}
if ( IsOpen() && props.selectable_fd >= 0 )
read->push_back(props.selectable_fd);
read->Insert(props.selectable_fd);
}
double PktSrc::NextTimestamp(double* local_network_time)

View file

@ -388,8 +388,8 @@ private:
// IOSource interface implementation.
virtual void Init();
virtual void Done();
virtual void GetFds(std::vector<int>* read, std::vector<int>* write,
std::vector<int>* except);
virtual void GetFds(iosource::FD_Set* read, iosource::FD_Set* write,
iosource::FD_Set* except);
virtual double NextTimestamp(double* local_network_time);
virtual void Process();
virtual const char* Tag();