From 916212e16fec87fcd96d59f5087308ffc2385cab Mon Sep 17 00:00:00 2001 From: sbund <sbund@wiback.org> Date: Fri, 7 Jul 2006 09:56:50 +0000 Subject: [PATCH] --- Scheduler/scheduler.cc | 62 ++++++ Scheduler/scheduler.hh | 388 ++++++++++++++++++++++++++++++++++++ Scheduler/scheduler.test.cc | 50 +++++ Utils/Exception.cc | 46 +++++ Utils/Exception.hh | 53 +++++ 5 files changed, 599 insertions(+) create mode 100644 Scheduler/scheduler.cc create mode 100644 Scheduler/scheduler.hh create mode 100644 Scheduler/scheduler.test.cc create mode 100644 Utils/Exception.cc create mode 100644 Utils/Exception.hh diff --git a/Scheduler/scheduler.cc b/Scheduler/scheduler.cc new file mode 100644 index 000000000..f17d16918 --- /dev/null +++ b/Scheduler/scheduler.cc @@ -0,0 +1,62 @@ +// $Id$ +// +// Copyright (C) 2006 +// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS) +// Kompetenzzentrum fuer Satelitenkommunikation (SatCom) +// Stefan Bund <stefan.bund@fokus.fraunhofer.de> +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the +// Free Software Foundation, Inc., +// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +// Definition of non-inline non-template functions + +//#include "scheduler.hh" +//#include "scheduler.ih" + +// Custom includes +#include <errno..h> +#include <sys/epoll.h> + +static const int EPollInitialSize = 16; + +#define prefix_ +///////////////////////////////cc.p//////////////////////////////////////// + +prefix_ Scheduler & satcom::lib::Scheduler::instance() +{ + static Scheduler instance; + return instance; +} + +prefix_ satcom::lib::Scheduler::Scheduler() + : epollFd_(epoll_create(EPollInitialSize)) +{ + +} + +prefix_ char const * satcom::SystemException::what() + const throw() +{ + return strerror(this->errno); +} + +///////////////////////////////cc.e//////////////////////////////////////// +#undef prefix_ + + +// Local Variables: +// mode: c++ +// c-file-style: "satcom" +// End: diff --git a/Scheduler/scheduler.hh b/Scheduler/scheduler.hh new file mode 100644 index 000000000..769876022 --- /dev/null +++ b/Scheduler/scheduler.hh @@ -0,0 +1,388 @@ +// $Id$ +// +// Copyright (C) 2006 +// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS) +// Kompetenzzentrum fuer Satelitenkommunikation (SatCom) +// Stefan Bund <stefan.bund@fokus.fraunhofer.de> +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the +// Free Software Foundation, Inc., +// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +#ifndef HH_scheduler_ +#define HH_scheduler_ 1 + +// Custom includes +#include <boost/function.hpp> +#include <boost/utility.hpp> +#include "SatLib/Utils/Exception.hh" + +//#include "scheduler.mpp" +///////////////////////////////hh.p//////////////////////////////////////// + +namespace satcom { +namespace lib { + + /** \brief Singleton class to manage the event loop + + This class manages a single select() type event loop. A + customer of this class may register any number of file + descriptiors with this class and pass callback functions to be + called on input, output or error. This functions are specified + using boost::function objects + */ + class Scheduler + : boost::noncopyable + { + public: + /////////////////////////////////////////////////////////////////////////// + // Types + + typedef boost::function<void (int fd)> callback; + enum events { EV_READ=1, EV_WRITE=2, EV_HUP=4, EV_ERR=8, EV_ALL= }; + + /////////////////////////////////////////////////////////////////////////// + ///\name Structors and default members + ///@{ + + // private default constructor + // no copy constructor + // no copy assignment + // default destructor + // no conversion constructors + + static Scheduler & instance(); + + ///@} + /////////////////////////////////////////////////////////////////////////// + + void add(int fd, callback const & cb, events eventMask = EV_ALL); + void remove(int fd, events eventMask = EV_ALL); + + protected: + + private: + Scheduler(); + + struct EventSpec + { + callback cb_read; + callback cb_write; + callback cb_hup; + callback cb_err; + }; + + typedef std::map<int,EventSpec> FdTable; + + FdTable fdTable_; + int epollFd_; + }; + + + \param b begin iterator of byte range to create the Packet + from + \param e corresponding end iterator + \return smart pointer to new packet + \throws TruncatedPacketException The data cannot be parsed + securely (the data might be trunctated or just + plain invalid) + */ + template <class OtherPacket, class InputIterator> + static typename ptr_t<OtherPacket>::ptr create(InputIterator b, InputIterator e); + +# define BOOST_PP_ITERATION_PARAMS_1 (4, (1, 9, "Packet.mpp", 5)) +# include BOOST_PP_ITERATE() + + ///@} + + ///\name Interpreter chain + ///@{ + + /** \brief get next packet from the interpreter chain + \return smart pointer to next packet or 0 if last packet */ + ptr next() const; + /** \brief get previous packet from the interpreter chain + \return smart pointer to previous packet or 0 if last packet */ + ptr prev() const; + /** \brief first packet of the interpreter chain + \return smart pointer to first packet */ + ptr head() const; + /** \brief get last packet of the interpreter chain + \return smart pointer to last packet */ + ptr last() const; + + /** \brief first packet of given type after the current packet + \return smart pointer to first following packet of type \a + OtherPacket or 0, if no such packet exists */ + template <class OtherPacket> typename ptr_t<OtherPacket>::ptr find_next() const; + /** \brief first packet of given type before the current packet + \return smart pointer to first preceding packet of type \a + OtherPacket or 0, if no such packet exists */ + template <class OtherPacket> typename ptr_t<OtherPacket>::ptr find_prev() const; + + /** \brief first packet of given type after the current packet + \return smart pointer to first following packet of type \a + OtherPacket. \e Assert's, that a packet of this type exists */ + template <class OtherPacket> typename ptr_t<OtherPacket>::ptr get_next() const; + /** \brief first packet of given type before the current packet + \return smart pointer to first preceding packet of type \a + OtherPacket. \e Assert's, that a packet of this type exists */ + template <class OtherPacket> typename ptr_t<OtherPacket>::ptr get_prev() const; + + /** \brief check, wether the packet is of the given type + \return true, if packt is of type \a OtherPacket, false + otherwise */ + template <class OtherPacket> bool is() const; + /** \brief cast packet pointer to the given type + \return a properly cast smart pointer if packet is of type + \a OtherPacket. Otherwise return 0 */ + template <class OtherPacket> typename ptr_t<OtherPacket>::ptr as(); + + /** \brief replace current packet interpreter + + This method will \e replace the current packet facade in + the interpreter list with a new interpreter given by \a + OtherPacket. + + \attention This invalidates the packet instance \e + this</b>. You must ensure, not to use the Packet instance + any further after this call + + This overload is used, if the \a OtherPacket constructor + takes no further arguments beyond the data range. If the + constructor needs further arguments, provide these + arguments to the \a reinterpret call. The compiler will + select the correct \a reinterpret overload to use. + + \return smart pointer to a \e new packet facade + \throws TruncatedPacketException there is not enough data + to savely interpret the packet as the given type. The + original packet is \e not invalidated + */ + template <class OtherPacket> + typename ptr_t<OtherPacket>::ptr reinterpret(); + template <class OtherPacket, class A0> + typename ptr_t<OtherPacket>::ptr reinterpret(A0 const & a0); + +# define BOOST_PP_ITERATION_PARAMS_1 (4, (2, 9, "Packet.mpp", 1)) +# include BOOST_PP_ITERATE() + + ///@} + + ///\name Raw packet data + ///@{ + + /** \brief begin interator of raw packet data + + This iterator allows access to the raw data interpreted by + the packet facade. This \e includes any header possibly + interpreted by the derived packet instance. To access the + payload of the packet, use next()->begin(). + + \return random access iterator to the begin of the raw + data */ + iterator begin() const; + /** \brief past-the-end iterator of raw packet data + + This iterator allows access to the raw data interpreted by + the packet facade. This \e includes any header possibly + interpreted by the derived packet instance. To access the + payload of the packet, use next()->end(). + + \return random access past-the-end iterator of the raw + data */ + iterator end() const; + /** \brief raw data size of packet + \return size of the raw data interpreted by this + packet in bytes. This is \e not necessarily the size of + the complete packet, use head()->size() for this. */ + size_t size() const; + + // Modifying the raw packet data + + // FIXME: Make all data mutators protected? + + /** \brief insert single byte \a v + + \attention The change will \e not be validated by the + derived packet instance. This method is mostly to be used + by the derived class implementation and their helper + classes. */ + void insert(iterator pos, byte v); + /** \brief insert \a n copies of byte \a v + \attention The change will \e not be validated by the + derived packet instance. This method is mostly to be used + by the derived class implementation and their helper + classes. */ + void insert(iterator pos, size_type n, byte v); + /** \brief insert a copy of the given range + \attention The change will \e not be validated by the + derived packet instance. This method is mostly to be used + by the derived class implementation and their helper + classes. */ + template <class InputIterator> + void insert(iterator pos, InputIterator f, InputIterator l); + + /** \brief erase single byte + \attention The change will \e not be validated by the + derived packet instance. This method is mostly to be used + by the derived class implementation and their helper + classes. */ + void erase(iterator pos); + /** \brief erase range + \attention The change will \e not be validated by the + derived packet instance. This method is mostly to be used + by the derived class implementation and their helper + classes. */ + void erase(iterator first, iterator last); + + ///@} + + protected: + ///\name Derived class interface + ///@{ + + /** \brief create new interpreter facade for an existing packet + + This constructor is called, when a new interpreter is to + be added to the interpreter chain. The constructor is + called indirectly from registerInterpreter() or + reinterpret() via the derived classes template + constructor. + */ + template <class Operation> + Packet(Operation const & arg); + virtual ~Packet(); + + private: + /** \brief create next packet interpreter + + This method is called by next(), last() or find_next() to + create any missing interpreters in the interpreter + chain. This method must be overridden in the derived class + to register the next packet interpreter in the interpreter + chain with the packet framework. + + To register the new interpreter, use + registerInterpreter() to create the new Packet + instance. The new instance is automatically added to the + interpreter chain after the current interpreter. + + See also satcom::pkf::PacketRegistryMixin on how to + use a Registry to find the next interpreters implementing + class. + */ + virtual void v_nextInterpreter() const = 0; + + /** \brief finalize packet for sending + + This method is called by the packet framework to let the + interpreter facade do some final calculations/packet + cleanup before the packet is sent out or digested in some + other way. This is the place to calcaulate checksums and + such. + + This method is autmatically called for all interpreters on + the interpreter chain. + */ + virtual void v_finalize() = 0; + + protected: + /** \brief add interpreter to interpreter chain + + This method is used by v_nextInterpreter() in the derived + classes to add a new interpreter to the interpreter + chain. This method will call \c OtherPacket's constructor + with the correct arguments and insert the new interpreter + into the interpreter list. This method is used, if no + further arguments are to be passed to the \c OtherPacket + constructor. If additional arguments are necessary, just + add them after \c end. The compiler will then choose the + correct overload to use. + */ + template <class OtherPacket> + typename ptr_t<OtherPacket>::ptr registerInterpreter( + raw_container::iterator begin, raw_container::iterator end) const; + template <class OtherPacket, class A0> + typename ptr_t<OtherPacket>::ptr registerInterpreter( + raw_container::iterator begin, raw_container::iterator end, + A0 const & a0) const; + +# define BOOST_PP_ITERATION_PARAMS_1 (4, (2, 9, "Packet.mpp", 3)) +# include BOOST_PP_ITERATE() + + ///@} + + private: + + ///\name Implementation + ///@{ + + void add_ref() const; + bool release(); + bool unlink(); + + struct PacketOp_register; + friend class PacketOp_register; + void i_registerInterpreter(Packet * p) const; + + struct PacketOp_replace; + friend class PacketOp_replace; + void i_replaceInterpreter(Packet * p); + + struct PacketOp_set; + friend class PacketOp_set; + void i_setInterpreter(impl::PacketImpl * i); + + private: + friend class impl::PacketImpl; + template <class OtherPacket> friend class impl::PkReg_EntryImpl; + + impl::PacketImpl* impl_; + size_type begin_; + size_type end_; + interpreter_list::iterator self_; + mutable bool parsed_; + mutable refcount_t refcount_; + + ///@} + }; + + /** \brief smart pointer handling + \relates Packet */ + void intrusive_ptr_add_ref(Packet const *); + /** \brief smart pointer handling + \relates Packet */ + void intrusive_ptr_release(Packet *); + + struct SystemException : public std::exception + { + SystemException(errno_) : errno(errno_) {}; + virtual char const * what() const throw(); + int errno; + } + +}} + +///////////////////////////////hh.e//////////////////////////////////////// +//#include "scheduler.cci" +//#include "scheduler.ct" +//#include "scheduler.cti" +#endif + + +// Local Variables: +// mode: c++ +// c-file-style: "satcom" +// End: diff --git a/Scheduler/scheduler.test.cc b/Scheduler/scheduler.test.cc new file mode 100644 index 000000000..4ce4d75ce --- /dev/null +++ b/Scheduler/scheduler.test.cc @@ -0,0 +1,50 @@ +// $Id$ +// +// Copyright (C) 2006 +// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS) +// Kompetenzzentrum fuer Satelitenkommunikation (SatCom) +// Stefan Bund <stefan.bund@fokus.fraunhofer.de> +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the +// Free Software Foundation, Inc., +// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +// Unit tests + +//#include "scheduler.test.hh" +//#include "scheduler.test.ih" + +// Custom includes + +#include <boost/test/auto_unit_test.hpp> +#include <boost/test/test_tools.hpp> + +#define prefix_ +///////////////////////////////cc.p//////////////////////////////////////// + +using namespace sastcom::lib; + +BOOST_AUTO_UNIT_TEST(scheduler) +{ + BOOST_CHECK_NO_THROW( Scheduler::instance() ); +} + +///////////////////////////////cc.e//////////////////////////////////////// +#undef prefix_ + + +// Local Variables: +// mode: c++ +// c-file-style: "satcom" +// End: diff --git a/Utils/Exception.cc b/Utils/Exception.cc new file mode 100644 index 000000000..fc48e4d77 --- /dev/null +++ b/Utils/Exception.cc @@ -0,0 +1,46 @@ +// $Id$ +// +// Copyright (C) 2006 +// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS) +// Kompetenzzentrum fuer Satelitenkommunikation (SatCom) +// Stefan Bund <stefan.bund@fokus.fraunhofer.de> +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the +// Free Software Foundation, Inc., +// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +// Definition of non-inline non-template functions + +//#include "Exception.hh" +//#include "Exception.ih" + +// Custom includes + +#define prefix_ +///////////////////////////////cc.p//////////////////////////////////////// + +prefix_ char const * satcom::SystemException::what() + const throw() +{ + return strerror(this->errno); +} + +///////////////////////////////cc.e//////////////////////////////////////// +#undef prefix_ + + +// Local Variables: +// mode: c++ +// c-file-style: "satcom" +// End: diff --git a/Utils/Exception.hh b/Utils/Exception.hh new file mode 100644 index 000000000..7ec23e23e --- /dev/null +++ b/Utils/Exception.hh @@ -0,0 +1,53 @@ +// $Id$ +// +// Copyright (C) 2006 +// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS) +// Kompetenzzentrum fuer Satelitenkommunikation (SatCom) +// Stefan Bund <stefan.bund@fokus.fraunhofer.de> +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the +// Free Software Foundation, Inc., +// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +#ifndef HH_Exception_ +#define HH_Exception_ 1 + +// Custom includes + +//#include "Exception.mpp" +///////////////////////////////hh.p//////////////////////////////////////// + +namespace satcom { +namespace lib { + + struct SystemException : public std::exception + { + SystemException(errno_) : errno(errno_) {}; + virtual char const * what() const throw(); + int errno; + } + +}} + +///////////////////////////////hh.e//////////////////////////////////////// +//#include "Exception.cci" +//#include "Exception.ct" +//#include "Exception.cti" +#endif + + +// Local Variables: +// mode: c++ +// c-file-style: "satcom" +// End: -- GitLab