From 59c54a0fc62025e128f02eae718052c6c24ce532 Mon Sep 17 00:00:00 2001 From: Jon Siwek Date: Tue, 9 Sep 2014 16:28:04 -0500 Subject: [PATCH] Add a simple FD_Set wrapper/helper class. --- src/ChunkedIO.cc | 14 +++---- src/ChunkedIO.h | 14 +++---- src/DNS_Mgr.cc | 6 +-- src/DNS_Mgr.h | 4 +- src/RemoteSerializer.cc | 22 +++++------ src/RemoteSerializer.h | 4 +- src/Serializer.cc | 6 +-- src/Serializer.h | 4 +- src/iosource/FD_Set.h | 83 ++++++++++++++++++++++++++++++++++++++++ src/iosource/IOSource.h | 6 +-- src/iosource/Manager.cc | 39 ++++--------------- src/iosource/Manager.h | 19 ++++++--- src/iosource/PktSrc.cc | 6 +-- src/iosource/PktSrc.h | 4 +- src/threading/Manager.cc | 4 +- src/threading/Manager.h | 4 +- 16 files changed, 149 insertions(+), 90 deletions(-) create mode 100644 src/iosource/FD_Set.h diff --git a/src/ChunkedIO.cc b/src/ChunkedIO.cc index a94eb98748..722b209bcd 100644 --- a/src/ChunkedIO.cc +++ b/src/ChunkedIO.cc @@ -630,11 +630,11 @@ bool ChunkedIOFd::IsFillingUp() return stats.pending > MAX_BUFFERED_CHUNKS_SOFT; } -std::vector ChunkedIOFd::FdSupplements() const +iosource::FD_Set ChunkedIOFd::ExtraReadFDs() const { - std::vector rval; - rval.push_back(write_flare.FD()); - rval.push_back(read_flare.FD()); + iosource::FD_Set rval; + rval.Insert(write_flare.FD()); + rval.Insert(read_flare.FD()); return rval; } @@ -1140,10 +1140,10 @@ bool ChunkedIOSSL::IsFillingUp() return false; } -std::vector ChunkedIOSSL::FdSupplements() const +iosource::FD_Set ChunkedIOSSL::ExtraReadFDs() const { - std::vector rval; - rval.push_back(write_flare.FD()); + iosource::FD_Set rval; + rval.Insert(write_flare.FD()); return rval; } diff --git a/src/ChunkedIO.h b/src/ChunkedIO.h index c640e529b8..b590453a72 100644 --- a/src/ChunkedIO.h +++ b/src/ChunkedIO.h @@ -7,8 +7,8 @@ #include "List.h" #include "util.h" #include "Flare.h" +#include "iosource/FD_Set.h" #include -#include #ifdef NEED_KRB5_H # include @@ -98,8 +98,8 @@ public: // Returns supplementary file descriptors that become read-ready in order // to signal that there is some work that can be performed. - virtual std::vector FdSupplements() const - { return std::vector(); } + virtual iosource::FD_Set ExtraReadFDs() const + { return iosource::FD_Set(); } // Makes sure that no additional protocol data is written into // the output stream. If this is activated, the output cannot @@ -183,7 +183,7 @@ public: virtual void Clear(); virtual bool Eof() { return eof; } virtual int Fd() { return fd; } - virtual std::vector FdSupplements() const; + virtual iosource::FD_Set ExtraReadFDs() const; virtual void Stats(char* buffer, int length); private: @@ -271,7 +271,7 @@ public: virtual void Clear(); virtual bool Eof() { return eof; } virtual int Fd() { return socket; } - virtual std::vector FdSupplements() const; + virtual iosource::FD_Set ExtraReadFDs() const; virtual void Stats(char* buffer, int length); private: @@ -340,8 +340,8 @@ public: virtual bool Eof() { return io->Eof(); } virtual int Fd() { return io->Fd(); } - virtual std::vector FdSupplements() const - { return io->FdSupplements(); } + virtual iosource::FD_Set ExtraReadFDs() const + { return io->ExtraReadFDs(); } virtual void Stats(char* buffer, int length); void EnableCompression(int level) diff --git a/src/DNS_Mgr.cc b/src/DNS_Mgr.cc index e7f7f218c0..2c049ba803 100644 --- a/src/DNS_Mgr.cc +++ b/src/DNS_Mgr.cc @@ -1216,10 +1216,10 @@ void DNS_Mgr::IssueAsyncRequests() } } -void DNS_Mgr::GetFds(std::vector* read, std::vector* write, - std::vector* except) +void DNS_Mgr::GetFds(iosource::FD_Set* read, iosource::FD_Set* write, + iosource::FD_Set* except) { - read->push_back(nb_dns_fd(nb_dns)); + read->Insert(nb_dns_fd(nb_dns)); } double DNS_Mgr::NextTimestamp(double* network_time) diff --git a/src/DNS_Mgr.h b/src/DNS_Mgr.h index d4071a3a0d..d8f420e6cc 100644 --- a/src/DNS_Mgr.h +++ b/src/DNS_Mgr.h @@ -132,8 +132,8 @@ protected: void DoProcess(bool flush); // IOSource interface. - virtual void GetFds(std::vector* read, std::vector* write, - std::vector* except); + virtual void GetFds(iosource::FD_Set* read, iosource::FD_Set* write, + iosource::FD_Set* except); virtual double NextTimestamp(double* network_time); virtual void Process(); virtual const char* Tag() { return "DNS_Mgr"; } diff --git a/src/RemoteSerializer.cc b/src/RemoteSerializer.cc index e23ea775dc..8762f491e4 100644 --- a/src/RemoteSerializer.cc +++ b/src/RemoteSerializer.cc @@ -1367,17 +1367,14 @@ void RemoteSerializer::Unregister(ID* id) } } -void RemoteSerializer::GetFds(std::vector* read, std::vector* write, - std::vector* except) +void RemoteSerializer::GetFds(iosource::FD_Set* read, iosource::FD_Set* write, + iosource::FD_Set* except) { - read->push_back(io->Fd()); - std::vector supp = io->FdSupplements(); - - for ( size_t i = 0; i < supp.size(); ++i ) - read->push_back(supp[i]); + read->Insert(io->Fd()); + read->Aggregate(io->ExtraReadFDs()); if ( io->CanWrite() ) - write->push_back(io->Fd()); + write->Insert(io->Fd()); } double RemoteSerializer::NextTimestamp(double* local_network_time) @@ -3390,11 +3387,9 @@ void SocketComm::Run() FD_ZERO(&fd_write); FD_ZERO(&fd_except); - int max_fd = 0; - + int max_fd = io->Fd(); FD_SET(io->Fd(), &fd_read); - max_fd = io->Fd(); - fd_vector_set(io->FdSupplements(), &fd_read, &max_fd); + max_fd = std::max(max_fd, io->ExtraReadFDs().Set(&fd_read)); loop_over_list(peers, i) { @@ -3403,7 +3398,8 @@ void SocketComm::Run() FD_SET(peers[i]->io->Fd(), &fd_read); if ( peers[i]->io->Fd() > max_fd ) max_fd = peers[i]->io->Fd(); - fd_vector_set(peers[i]->io->FdSupplements(), &fd_read, &max_fd); + max_fd = std::max(max_fd, + peers[i]->io->ExtraReadFDs().Set(&fd_read)); } else { diff --git a/src/RemoteSerializer.h b/src/RemoteSerializer.h index ebc990f243..2af7610a7c 100644 --- a/src/RemoteSerializer.h +++ b/src/RemoteSerializer.h @@ -140,8 +140,8 @@ public: void Finish(); // Overidden from IOSource: - virtual void GetFds(std::vector* read, std::vector* write, - std::vector* 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 TimerMgr::Tag* GetCurrentTag(); diff --git a/src/Serializer.cc b/src/Serializer.cc index 1a637f6576..7306b0ded0 100644 --- a/src/Serializer.cc +++ b/src/Serializer.cc @@ -1068,10 +1068,10 @@ void EventPlayer::GotFunctionCall(const char* name, double time, // We don't replay function calls. } -void EventPlayer::GetFds(std::vector* read, std::vector* write, - std::vector* except) +void EventPlayer::GetFds(iosource::FD_Set* read, iosource::FD_Set* write, + iosource::FD_Set* except) { - read->push_back(fd); + read->Insert(fd); } double EventPlayer::NextTimestamp(double* local_network_time) diff --git a/src/Serializer.h b/src/Serializer.h index 6640afc722..558dce2086 100644 --- a/src/Serializer.h +++ b/src/Serializer.h @@ -355,8 +355,8 @@ public: EventPlayer(const char* file); virtual ~EventPlayer(); - virtual void GetFds(std::vector* read, std::vector* write, - std::vector* 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() { return "EventPlayer"; } diff --git a/src/iosource/FD_Set.h b/src/iosource/FD_Set.h new file mode 100644 index 0000000000..43e7c37fc4 --- /dev/null +++ b/src/iosource/FD_Set.h @@ -0,0 +1,83 @@ +#ifndef BRO_FD_SET_H +#define BRO_FD_SET_H + +#include +#include + +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::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::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::const_iterator it = fds.begin(); it != fds.end(); + ++it ) + if ( FD_ISSET(*it, set) ) + return true; + return false; + } + +private: + + int max; + std::set fds; +}; + +} // namespace bro + +#endif // BRO_FD_SET_H diff --git a/src/iosource/IOSource.h b/src/iosource/IOSource.h index 630a7fcf11..df82012268 100644 --- a/src/iosource/IOSource.h +++ b/src/iosource/IOSource.h @@ -8,8 +8,7 @@ extern "C" { } #include -#include - +#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* read, std::vector* write, - std::vector* 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 diff --git a/src/iosource/Manager.cc b/src/iosource/Manager.cc index 4259087e40..41118bdbfe 100644 --- a/src/iosource/Manager.cc +++ b/src/iosource/Manager.cc @@ -44,15 +44,6 @@ void Manager::RemoveAll() dont_counts = sources.size(); } -static void fd_vector_set(const std::vector& 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& 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)); } diff --git a/src/iosource/Manager.h b/src/iosource/Manager.h index a18d433d66..288ec74352 100644 --- a/src/iosource/Manager.h +++ b/src/iosource/Manager.h @@ -5,8 +5,7 @@ #include #include -#include -#include +#include "iosource/FD_Set.h" namespace iosource { @@ -115,11 +114,19 @@ private: struct Source { IOSource* src; - std::vector fd_read; - std::vector fd_write; - std::vector 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 SourceList; diff --git a/src/iosource/PktSrc.cc b/src/iosource/PktSrc.cc index 963f37cb83..6ee95a48a1 100644 --- a/src/iosource/PktSrc.cc +++ b/src/iosource/PktSrc.cc @@ -218,8 +218,8 @@ void PktSrc::Done() Close(); } -void PktSrc::GetFds(std::vector* read, std::vector* write, - std::vector* 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* read, std::vector* 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) diff --git a/src/iosource/PktSrc.h b/src/iosource/PktSrc.h index 8705ec48f3..9c05115257 100644 --- a/src/iosource/PktSrc.h +++ b/src/iosource/PktSrc.h @@ -388,8 +388,8 @@ private: // IOSource interface implementation. virtual void Init(); virtual void Done(); - virtual void GetFds(std::vector* read, std::vector* write, - std::vector* 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(); diff --git a/src/threading/Manager.cc b/src/threading/Manager.cc index 19ee948a1c..449f2a8ad1 100644 --- a/src/threading/Manager.cc +++ b/src/threading/Manager.cc @@ -65,8 +65,8 @@ void Manager::AddMsgThread(MsgThread* thread) msg_threads.push_back(thread); } -void Manager::GetFds(std::vector* read, std::vector* write, - std::vector* except) +void Manager::GetFds(iosource::FD_Set* read, iosource::FD_Set* write, + iosource::FD_Set* except) { } diff --git a/src/threading/Manager.h b/src/threading/Manager.h index e208bb64c1..70e592fa10 100644 --- a/src/threading/Manager.h +++ b/src/threading/Manager.h @@ -103,8 +103,8 @@ protected: /** * Part of the IOSource interface. */ - virtual void GetFds(std::vector* read, std::vector* write, - std::vector* except); + virtual void GetFds(iosource::FD_Set* read, iosource::FD_Set* write, + iosource::FD_Set* except); /** * Part of the IOSource interface.