// +----------------------------------------------------+
// | stuffer |
// | |
-// [ udpReader ] O-->:---> [ queue ] -->O [ ] |
-// | [ join ] -->O [ rateFilter] O-->:O--> [ udpWriter ]
+// [ udpSource ] O-->:---> [ queue ] -->O [ ] |
+// | [ join ] -->O [ rateFilter] O-->:O--> [ udpSink ]
// | [ generator ] -->O [ ] |
// | |
// +----------------------------------------------------+
senf::ConnectedUDPv4ClientSocketHandle outputSocket(
senf::INet4SocketAddress("localhost:44345"));
- module::ActiveSocketReader<> udpReader ( inputSocket );
+ module::ActiveSocketSource<> udpSource ( inputSocket );
RateStuffer stuffer ( 1000000000ul,
senf::DataPacket::create(std::string("<idle>\n")),
2u, 1u );
- module::PassiveSocketWriter<> udpWriter ( outputSocket );
+ module::PassiveSocketSink<> udpSink ( outputSocket );
- ppi::connect( udpReader, stuffer );
- ppi::connect( stuffer, udpWriter );
+ ppi::connect( udpSource, stuffer );
+ ppi::connect( stuffer, udpSink );
ppi::run();
CloneSource will provide clone's of a template \a packet on it's \a output.
- \ingroup sourcesink_modules
+ \ingroup io_modules
*/
class CloneSource
: public Module
All passive connectors call some onRequest callback whenever I/O needs to be performed. All
input modules possess a packet queue.
- We therefore have 4 connector types: senf::ppi::ActiveInput, senf::ppi::ActiveOutput,
- senf::ppi::PassiveInput and senf::ppi::PassiveOutput.
+ We therefore have 4 connector types:
+ \li senf::ppi::connector::ActiveInput
+ \li senf::ppi::connector::ActiveOutput
+ \li senf::ppi::connector::PassiveInput
+ \li senf::ppi::connector::PassiveOutput.
+
+ Connectors are declared as module data members and are then externally connected to other
+ modules.
+
+ \see
+ senf::ppi::module::Module \n
+ senf::ppi::connect()
+ \ref ppi_connectors
*/
/** \brief Connector base-class
///////////////////////////////cti.p///////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
-// senf::ppi::module::debug::LogWriter<Stream,Area,level>
+// senf::ppi::module::debug::LogSink<Stream,Area,level>
template <class Stream, class Area, senf::log::Level level>
-prefix_ senf::ppi::module::debug::LogWriter<Stream,Area,level>::LogWriter()
+prefix_ senf::ppi::module::debug::LogSink<Stream,Area,level>::LogSink()
{
noroute(input);
- input.onRequest(&LogWriter::request);
+ input.onRequest(&LogSink::request);
}
////////////////////////////////////////
// private members
template <class Stream, class Area, senf::log::Level level>
-prefix_ void senf::ppi::module::debug::LogWriter<Stream,Area,level>::request()
+prefix_ void senf::ppi::module::debug::LogSink<Stream,Area,level>::request()
{
Packet packet (input());
SENF_LOG_BLOCK((Stream)(Area)(level)({
template < class Stream = log::Debug,
class Area = log::DefaultArea,
senf::log::Level level = log::VERBOSE >
- class LogWriter
+ class LogSink
: public module::Module
{
- SENF_PPI_MODULE(LogWriter);
+ SENF_PPI_MODULE(LogSink);
public:
connector::PassiveInput input;
- LogWriter();
+ LogSink();
private:
void request();
BOOST_CHECK( source.empty() );
}
-BOOST_AUTO_UNIT_TEST(logWriter)
+BOOST_AUTO_UNIT_TEST(logSink)
{
debug::ActiveFeederSource source;
- debug::LogWriter<> sink;
+ debug::LogSink<> sink;
ppi::connect(source,sink);
senf::PacketData::byte data[] = { 0x13u, 0x24u, 0x35u };
DiscardSink will accept any number of packets and will silently discard them.
- \ingroup sourcesink_modules
+ \ingroup io_modules
*/
class DiscardSink
: public Module
\section event_impl Implementing Events
All events are derived from EventImplementation which is based on EventDescriptor.
- \see EventImplementation
+ \see EventImplementation \n
+ \ref ppi_events
*/
// Implementation: The concrete EventDescriptor implementation will need to set things up so
/** \brief Generic event interface base-class
The EventDescriptor base-class provides an interface to control events.
+
+ \see \ref ppi_events
*/
class EventDescriptor
{
BOOST_AUTO_UNIT_TEST(ioEvent)
{
- // Tested in SocketReader.test.cc and SocketWriter.test.cc
+ // Tested in SocketSource.test.cc and SocketSink.test.cc
}
///////////////////////////////cc.e////////////////////////////////////////
<li>\ref ppi_connections</li>
<li>\ref ppi_throttling</li>
<li>\ref ppi_events</li>
+ <li>\ref ppi_run</li>
<li>\ref ppi_flows</li>
</ol>
</div>
\see senf::ppi::EventDescriptor
+ \section ppi_run Running the network
+
+ After the network has been set up, senf::ppi::run() is called to execute it. This call will only
+ return after all data has been processed. The PPI knows this, when no events are enabled any
+ more. Without events, nothing will happen any more since it is the events which drive the
+ PPI. Therefore the PPI surmises, that all data has been processed and returns from
+ senf::ppi::run().
+
+ This works very well with automatic throttling. When no data is available to be processed any
+ more and no more data can be expected to arrive (for Example since data has been read from a
+ file which is now exhausted) all events will be disabled automatically via trhottle
+ notifications and so signal that any processing should stop.
+
\section ppi_flows Information Flow
The above description conceptually introduces three different flow levels:
#else
template <class Target>
-prefix_ void senf::ppi::module::Module::registerEvent(Target target,
- EventDescriptor & descriptor)
+prefix_ void senf::ppi::module::Module::registerEvent(EventDescriptor & descriptor,
+ Target target)
{}
#endif
The PPI provided general purpose modules can be grouped into several categories
\li \ref io_modules receive external data or forward packets out of the PPI
- \li \ref sourcesink_modules generate or absorb packets internally
\li \ref routing_modules forward packets within the network
\li \ref adapter_modules are used to connect incompatible connectors to each other
\todo Implement Spliters: PassiveSplitter, PrioritySplitter, CloneSplitter
*/
- /** \defgroup io_modules Input/Output Modules
+ /** \defgroup io_modules Source/Sink Modules
- Input/Output Modules receive data from external sources or forward data from the PPI to
- outside targets.
- */
-
- /** \defgroup sourcesink_modules Source/Sink Modules
-
- Source and Sink modules generate or absorb packets internally. In contrast to \ref
- io_modules, they do not communicate outside the PPI.
+ Source and Sink modules generate or absorb packets in some way: Reading data from a file
+ descriptor, discarding packets etc.
*/
/** \defgroup routing_modules Routing Modules
.autoThrottling( false );
// Register event handlers
- registerEvent( &SomeModule::read, event );
+ registerEvent( event, &SomeModule::read );
// Register passive connector handlers
input.onRequest( &SomeModule::outputRequest );
If your module only has a single input connector, you should call this connector \c
input. If it has only a single output connector, you should call it \c output. This allows
to setup connections without stating the connector explicitly (see senf::ppi::connect()).
+
+ \see \ref ppi_modules
*/
class Module
: boost::noncopyable
\param[in] target Data target, object which controls
outgoing data (connector or event)
\returns Route instance describing this route
+ \see \ref ppi_throttling
\note The real implementation is not provided by three
overloads but by a single template member */
void registerEvent(Descriptor & descriptor, Target target);
#else
template <class Target>
- void registerEvent(Target target, EventDescriptor & descriptor);
+ void registerEvent(EventDescriptor & descriptor, Target target);
///< Register an external event
/**< The \a target argument may be either an arbitrary
callable object or it may be a member function pointer
\param[in] target The handler to call whenever the
event is signaled
- \param[in] descriptor The type of event to register */
+ \param[in] descriptor The type of event to register
+ \note The real implementation has the second arguments
+ type as an additional template parameter. */
#endif
ClockService::clock_type time() const; ///< Time-stamp of the currently processing event
/** \brief Connect modules
senf::ppi::connect() establishes a connection between two modules or, to be more precise,
- between two connectors. For enhanced usability, \a source and \a target may be a Connector,
- a Module or a collection/subnetwork. Passing a Module or collection/subnetwork as \a source
- will originate the connection on the \c output member of that Module or collection while
- passing a module or collection/subnetwork as \a target will terminate the connection on that
- Module or collections \c input member. For most simple modules, the specification of the
- connector is therefore obsolete.
-
- Furthermore, the connect() call may be extended by special modules (e.g. PassiveJoin which
- allows an arbitrary of input connections).
+ between two connectors. It will connect any input to any output connector as long as one is
+ active and the other passive.
+
+ If a module has an output connector called \c output, the module may be directly specified
+ as \a source argument. In the same way, if a module has an input connector called \c input,
+ the module may be given directly as \a target argument. This simplifies the most common case
+ of a module with one input and one output connector.
+
+ \see \ref ppi_connections
*/
- template <class Source, class Target>
- void connect(Source & source, Target & target);
+ void connect(connector::ActiveInput & source, connector::PassiveOutput & target);
+
+ /** \brief Connect modules
+ \see connect() */
+ void connect(connector::PassiveInput & source, connector::ActiveOutput & target);
#endif
enabled (Since the events are enabled and disabled by the throttle notifications which
depend among other things on the packet queues, this is the same as checking for packets in
any queue). It is Ok to call senf::ppi::run() multiple times during the program lifetime.
+
+ \see \ref ppi_run
*/
void run();
// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
/** \file
- \brief SocketWriter inline non-template implementation */
+ \brief SocketSink inline non-template implementation */
// Custom includes
///////////////////////////////cci.p///////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
-// senf::ppi::PacketWriter
+// senf::ppi::PacketSink
-prefix_ void senf::ppi::PacketWriter::operator()(Handle handle, Packet packet)
+prefix_ void senf::ppi::PacketSink::operator()(Handle handle, Packet packet)
{
handle.write(packet.data());
}
// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
/** \file
- \brief SocketWriter non-inline template implementation */
+ \brief SocketSink non-inline template implementation */
-//#include "SocketWriter.ih"
+//#include "SocketSink.ih"
// Custom includes
///////////////////////////////ct.p////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
-// senf::ppi::module::ActiveSocketWriter<Writer>
+// senf::ppi::module::ActiveSocketSink<Sink>
-template <class Writer>
-prefix_ senf::ppi::module::ActiveSocketWriter<Writer>::ActiveSocketWriter(Handle handle)
+template <class Sink>
+prefix_ senf::ppi::module::ActiveSocketSink<Sink>::ActiveSocketSink(Handle handle)
: handle_(handle), event_(handle_, IOEvent::Write), writer_()
{
- registerEvent( event_, &ActiveSocketWriter::write );
+ registerEvent( event_, &ActiveSocketSink::write );
route(input, event_);
}
////////////////////////////////////////
// private members
-template <class Writer>
-prefix_ void senf::ppi::module::ActiveSocketWriter<Writer>::write()
+template <class Sink>
+prefix_ void senf::ppi::module::ActiveSocketSink<Sink>::write()
{
writer_(handle_,input());
}
///////////////////////////////////////////////////////////////////////////
-// senf::ppi::module::PassiveSocketWriter<Writer>
+// senf::ppi::module::PassiveSocketSink<Sink>
-template <class Writer>
-prefix_ senf::ppi::module::PassiveSocketWriter<Writer>::PassiveSocketWriter(Handle handle)
+template <class Sink>
+prefix_ senf::ppi::module::PassiveSocketSink<Sink>::PassiveSocketSink(Handle handle)
: handle_(handle), writer_()
{
noroute(input);
- input.onRequest(&PassiveSocketWriter::write);
+ input.onRequest(&PassiveSocketSink::write);
}
////////////////////////////////////////
// private members
-template <class Writer>
-prefix_ void senf::ppi::module::PassiveSocketWriter<Writer>::write()
+template <class Sink>
+prefix_ void senf::ppi::module::PassiveSocketSink<Sink>::write()
{
writer_(handle_,input());
}
// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
/** \file
- \brief SocketWriter public header */
+ \brief SocketSink public header */
-#ifndef HH_SocketWriter_
-#define HH_SocketWriter_ 1
+#ifndef HH_SocketSink_
+#define HH_SocketSink_ 1
// Custom includes
#include "../Packets/Packets.hh"
#include "Module.hh"
#include "Connectors.hh"
-//#include "SocketWriter.mpp"
+//#include "SocketSink.mpp"
///////////////////////////////hh.p////////////////////////////////////////
namespace senf {
namespace ppi {
- /** \brief Write helper for module::ActiveSocketWriter / module::PassiveSocketWriter
+ /** \brief Write helper for module::ActiveSocketSink / module::PassiveSocketSink
This write helper will write the packets completely as datagrams to the given socket.
*/
- class PacketWriter
+ class PacketSink
{
public:
typedef senf::ClientSocketHandle<
/** \brief Output module writing data to arbitrary FileHandle
- This output module will write data to a FileHandle object using a given \a Writer. This
+ This output module will write data to a FileHandle object using a given \a Sink. This
output module is active. This requires the file handle to be able to signal its readiness to
accept more data via the Scheduler.
- The default \a Writer is senf::ppi::PacketWriter which will write out the complete packet to
+ The default \a Sink is senf::ppi::PacketSink which will write out the complete packet to
the file handle.
- A \a Writer must fulfill the following interface:
+ A \a Sink must fulfill the following interface:
\code
- class SomeWriter
+ class SomeSink
{
public:
typedef unspecified Handle; // type of handle requested
- SomeWriter(); // default constructible
+ SomeSink(); // default constructible
void operator()(Handle handle, Packet packet); // insertion function
};
\endcode
- Whenever a packet is received for sending, the \a Writer's \c operator() is called.
+ Whenever a packet is received for sending, the \a Sink's \c operator() is called.
\ingroup io_modules
*/
- template <class Writer=PacketWriter>
- class ActiveSocketWriter : public Module
+ template <class Sink=PacketSink>
+ class ActiveSocketSink : public Module
{
- SENF_PPI_MODULE(ActiveSocketWriter);
+ SENF_PPI_MODULE(ActiveSocketSink);
public:
- typedef typename Writer::Handle Handle; ///< Handle type requested by writer
+ typedef typename Sink::Handle Handle; ///< Handle type requested by writer
connector::ActiveInput input; ///< Input connector from which data is received
- ActiveSocketWriter(Handle handle); ///< Create new writer for the given handle
- /**< Data will be written to \a handle using \a Writer.
+ ActiveSocketSink(Handle handle); ///< Create new writer for the given handle
+ /**< Data will be written to \a handle using \a Sink.
\param[in] handle Handle to write data to */
private:
void write();
Handle handle_;
IOEvent event_;
- Writer writer_;
+ Sink writer_;
};
/** \brief Output module writing data to arbitrary FileHandle
- This output module will write data to a FileHandle object using a given \a Writer. This
+ This output module will write data to a FileHandle object using a given \a Sink. This
output module is passive. This implies, that the output handle may not block. This also
implies, that data will probably get lost if written to fast for the underlying transport
mechanism. Either this is desired (like for a UDP socket) or some additional bandwidth
shaping needs to be used.
- The default \a Writer is senf::ppi::PacketWriter which will write out the complete packet to
+ The default \a Sink is senf::ppi::PacketSink which will write out the complete packet to
the file handle.
- The \a Writer must fulfill the following interface:
+ The \a Sink must fulfill the following interface:
\code
- class SomeWriter
+ class SomeSink
{
public:
typedef unspecified Handle; // type of handle requested
- SomeWriter(); // default constructible
+ SomeSink(); // default constructible
void operator()(Handle handle, Packet packet); // insertion function
};
\endcode
- Whenever a packet is received for sending, the \a Writer's \c operator() is called.
+ Whenever a packet is received for sending, the \a Sink's \c operator() is called.
\ingroup io_modules
*/
- template <class Writer=PacketWriter>
- class PassiveSocketWriter : public Module
+ template <class Sink=PacketSink>
+ class PassiveSocketSink : public Module
{
- SENF_PPI_MODULE(PassiveSocketWriter);
+ SENF_PPI_MODULE(PassiveSocketSink);
public:
- typedef typename Writer::Handle Handle; ///< Handle type requested by writer
+ typedef typename Sink::Handle Handle; ///< Handle type requested by writer
connector::PassiveInput input; ///< Input connector from which data is received
- PassiveSocketWriter(Handle handle); ///< Create new writer for the given handle
- /**< Data will be written to \a handle using \a Writer.
+ PassiveSocketSink(Handle handle); ///< Create new writer for the given handle
+ /**< Data will be written to \a handle using \a Sink.
\param[in] handle Handle to write data to */
private:
void write();
Handle handle_;
- Writer writer_;
+ Sink writer_;
};
}}}
///////////////////////////////hh.e////////////////////////////////////////
-#include "SocketWriter.cci"
-#include "SocketWriter.ct"
-//#include "SocketWriter.cti"
+#include "SocketSink.cci"
+#include "SocketSink.ct"
+//#include "SocketSink.cti"
#endif
\f
// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
/** \file
- \brief SocketWriter.test unit tests */
+ \brief SocketSink.test unit tests */
-//#include "SocketWriter.test.hh"
-//#include "SocketWriter.test.ih"
+//#include "SocketSink.test.hh"
+//#include "SocketSink.test.ih"
// Custom includes
#include "../Socket/Protocols/INet/UDPSocketHandle.hh"
#include "../Socket/Protocols/INet/ConnectedUDPSocketHandle.hh"
-#include "SocketReader.hh"
+#include "SocketSource.hh"
#include "DebugModules.hh"
-#include "SocketWriter.hh"
+#include "SocketSink.hh"
#include "Setup.hh"
#include <boost/test/auto_unit_test.hpp>
}
}
-BOOST_AUTO_UNIT_TEST(passiveSocketWriter)
+BOOST_AUTO_UNIT_TEST(passiveSocketSink)
{
senf::ConnectedUDPv4ClientSocketHandle outputSocket (
senf::INet4SocketAddress("localhost:44344"));
- module::PassiveSocketWriter<> udpWriter(outputSocket);
+ module::PassiveSocketSink<> udpSink(outputSocket);
debug::ActiveSource source;
- ppi::connect(source, udpWriter);
+ ppi::connect(source, udpSink);
std::string data ("TEST");
senf::Packet p (senf::DataPacket::create(data));
BOOST_CHECK_EQUAL( data, input );
}
-BOOST_AUTO_UNIT_TEST(activeSocketWriter)
+BOOST_AUTO_UNIT_TEST(activeSocketSink)
{
senf::ConnectedUDPv4ClientSocketHandle outputSocket (
senf::INet4SocketAddress("localhost:44344"));
- module::ActiveSocketWriter<> udpWriter(outputSocket);
+ module::ActiveSocketSink<> udpSink(outputSocket);
debug::PassiveSource source;
- ppi::connect(source, udpWriter);
+ ppi::connect(source, udpSink);
std::string data ("TEST");
senf::Packet p (senf::DataPacket::create(data));
// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
/** \file
- \brief SocketReader non-inline template implementation */
+ \brief SocketSource non-inline template implementation */
-//#include "SocketReader.ih"
+//#include "SocketSource.ih"
// Custom includes
///////////////////////////////ct.p////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
-// senf::ppi::PacketReader<Packet>
+// senf::ppi::PacketSource<Packet>
template <class Packet>
-prefix_ Packet senf::ppi::PacketReader<Packet>::operator()(Handle handle)
+prefix_ Packet senf::ppi::PacketSource<Packet>::operator()(Handle handle)
{
Packet packet (Packet::create(Packet::noinit));
handle.read(packet.data(),0u);
}
///////////////////////////////////////////////////////////////////////////
-// senf::ppi::module::ActiveSocketReader<Reader>
+// senf::ppi::module::ActiveSocketSource<Source>
-template <class Reader>
-prefix_ senf::ppi::module::ActiveSocketReader<Reader>::
-ActiveSocketReader(Handle handle)
+template <class Source>
+prefix_ senf::ppi::module::ActiveSocketSource<Source>::
+ActiveSocketSource(Handle handle)
: handle_(handle), event_(handle_, IOEvent::Read), reader_()
{
- registerEvent( event_, &ActiveSocketReader::read );
+ registerEvent( event_, &ActiveSocketSource::read );
route(event_, output);
}
////////////////////////////////////////
// private members
-template <class Reader>
-prefix_ void senf::ppi::module::ActiveSocketReader<Reader>::read()
+template <class Source>
+prefix_ void senf::ppi::module::ActiveSocketSource<Source>::read()
{
output(reader_(handle_));
}
// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
/** \file
- \brief SocketReader public header */
+ \brief SocketSource public header */
-#ifndef HH_SocketReader_
-#define HH_SocketReader_ 1
+#ifndef HH_SocketSource_
+#define HH_SocketSource_ 1
// Custom includes
#include "../Packets/Packets.hh"
#include "Connectors.hh"
#include "IOEvent.hh"
-//#include "SocketReader.mpp"
+//#include "SocketSource.mpp"
///////////////////////////////hh.p////////////////////////////////////////
namespace senf {
namespace ppi {
- /** \brief Read helper for module::ActiveSocketReader
+ /** \brief Read helper for module::ActiveSocketSource
This read helper will read a datagram from a datagram socket. This datagram will then be
interpreted as a packet of type \a Packet as defined in the packet library. \a Packet
structure.
*/
template <class Packet=DataPacket>
- class PacketReader
+ class PacketSource
{
public:
typedef senf::ClientSocketHandle<
/** \brief Input module reading data from an arbitrary FileHandle
This input module will read data from a FileHandle object and parse the data according to
- the \a Reader. The default reader is senf::ppi::PacketReader <> which reads the data into a
+ the \a Source. The default reader is senf::ppi::PacketSource <> which reads the data into a
senf::DataPacket. To parse the data according to some other packet type, pass that packet
- type to senf::ppi::PacketReader:
+ type to senf::ppi::PacketSource:
\code
- senf::ppi::module::ActiveSocketReader< senf::ppi::PacketReader<senf::EthernetPacket> > reader;
+ senf::ppi::module::ActiveSocketSource< senf::ppi::PacketSource<senf::EthernetPacket> > reader;
\endcode
declares a \a reader module reading senf::EthrtnetPacket's.
- A \a Reader must fulfill the following interface:
+ A \a Source must fulfill the following interface:
\code
- class SomeReader
+ class SomeSource
{
public:
typedef unspecified_type Handle; // type of handle requested
- SomeReader(); // default constructible
+ SomeSource(); // default constructible
Packet operator()(Handle handle); // extraction function
};
\endcode
- Whenever the FileHandle object is ready for reading, the \a Reader's \c operator() is called
+ Whenever the FileHandle object is ready for reading, the \a Source's \c operator() is called
to read a packet.
\ingroup io_modules
*/
- template <class Reader=PacketReader<> >
- class ActiveSocketReader
+ template <class Source=PacketSource<> >
+ class ActiveSocketSource
: public Module
{
- SENF_PPI_MODULE(ActiveSocketReader);
+ SENF_PPI_MODULE(ActiveSocketSource);
public:
- typedef typename Reader::Handle Handle; ///< Handle type requested by the reader
+ typedef typename Source::Handle Handle; ///< Handle type requested by the reader
connector::ActiveOutput output; ///< Output connector to which the data received is written
- ActiveSocketReader(Handle handle); ///< Create new reader for the given handle
+ ActiveSocketSource(Handle handle); ///< Create new reader for the given handle
/**< Data will be read from \a handle and be parsed by \a
- Reader.
+ Source.
\param[in] handle Handle to read data from */
private:
Handle handle_;
IOEvent event_;
- Reader reader_;
+ Source reader_;
};
}}}
///////////////////////////////hh.e////////////////////////////////////////
-//#include "SocketReader.cci"
-#include "SocketReader.ct"
-//#include "SocketReader.cti"
+//#include "SocketSource.cci"
+#include "SocketSource.ct"
+//#include "SocketSource.cti"
#endif
\f
// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
/** \file
- \brief SocketReader.test unit tests */
+ \brief SocketSource.test unit tests */
-//#include "SocketReader.test.hh"
-//#include "SocketReader.test.ih"
+//#include "SocketSource.test.hh"
+//#include "SocketSource.test.ih"
// Custom includes
#include <algorithm>
#include "../Socket/Protocols/INet/UDPSocketHandle.hh"
#include "../Scheduler/Scheduler.hh"
-#include "SocketReader.hh"
+#include "SocketSource.hh"
#include "DebugModules.hh"
#include "Setup.hh"
}
}
-BOOST_AUTO_UNIT_TEST(socketReader)
+BOOST_AUTO_UNIT_TEST(socketSource)
{
senf::UDPv4ClientSocketHandle inputSocket;
inputSocket.bind(senf::INet4SocketAddress("localhost:44344"));
inputSocket.blocking(false);
- module::ActiveSocketReader<> udpReader(inputSocket);
+ module::ActiveSocketSource<> udpSource(inputSocket);
debug::PassiveSink sink;
- ppi::connect(udpReader, sink);
+ ppi::connect(udpSource, sink);
std::string data ("TEST");
env.Help("""
Additional top-level build targets:
+prepare Create all source files not part of the repository
all_tests Build and run unit tests for all modules
all_docs Build documentation for all modules
all Build everything
ENV = { 'TODAY' : str(datetime.date.today()),
'REVISION' : rev,
'LOGNAME' : logname, # needed by the debian build scripts
- 'CONCURRENCY_LEVEL' : env.GetOption('num_jobs') or "1"
+ 'CONCURRENCY_LEVEL' : env.GetOption('num_jobs') or "1",
+ 'SCONS' : 1
},
CONFIG_FILES = [ 'Doxyfile.local', 'SConfig', 'local_config.hh' ],
CONFIG_FILES_OPTS = configFilesOpts,
Export('env')
-# Create Doxyfile.local if not cleaning and the file does not exist
-# otherwise doxygen will barf on this non-existent file
+# Create Doxyfile.local otherwise doxygen will barf on this non-existent file
if not env.GetOption('clean') and not os.path.exists("Doxyfile.local"):
Execute(Touch("Doxyfile.local"))
###########################################################################
# Define build targets
+# Before defining any targets, check wether this is the first build in
+# pristine directory tree. If so, call 'scons prepare' so the dependencies
+# created later are correct
+
+if not env.GetOption('clean') and not os.path.exists(".prepare-stamp") \
+ and not os.environ.get("SCONS"):
+ env.Execute([ "scons prepare" ])
+
+env.Clean('all', '.prepare-stamp')
+
SConscript(glob.glob("*/SConscript"))
SENFSCons.StandardTargets(env)
Flatten([ env.File(SENFSCons.LibPath(lib)).sources for lib in env['ALLLIBS'] ]))
env.Default(libsenf)
env.Clean('all', 'libsenf.a')
-env.Alias('all', 'libsenf.a')
+env.Alias('default', 'libsenf.a')
env.Alias('install_all', env.Install('$LIBINSTALLDIR', libsenf))
'python doclib/fix-links.py -v -s .svn -s linklint -s debian linklint/errorX.txt linklint/errorAX.txt',
])
+PhonyTarget(env, 'prepare', [])
+
env.Clean('all', env.Dir('linklint'))
+
+env.Clean('all','.prepare-stamp')
+if not env.GetOption('clean') and not os.path.exists(".prepare-stamp"):
+ Execute(Touch(".prepare-stamp"))
\brief GenericAddressingPolicy public header
*/
+/** \defgroup addr_group Addressing classes
+ */
+
#ifndef HH_GenericAddressingPolicy_
#define HH_GenericAddressingPolicy_ 1
dh_testdir
# # Add here commands to configure the package.
rm -f Doxyfile.local SConfig local_config.hh
+ scons prepare
# If needed, we could create new files 'Doxyfile.local',
# 'SConfig' and/or 'local_config.hh' here. We don't remove them
# in 'clean' to allow building a source package from an
-# individually configured svn working copy.
+# individually configured svn working copy. (The files are ignored
+# by dpkg-buildpackge because of appropriate -I arguments provided
+# by 'scons deb' and 'scons debsrc'
touch configure-stamp
build: build-stamp
build-stamp: configure-stamp
dh_testdir
# # Add here commands to compile the package.
- scons -j $(CONCURRENCY_LEVEL) final=1
- scons -j $(CONCURRENCY_LEVEL) all_docs final=1
+ scons -j $(CONCURRENCY_LEVEL) default all_docs final=1
touch $@
clean:
dh_clean -k
dh_installdirs
# # Add here commands to install the package into debian/tmp
- scons install_all final=1\
+ scons install_all final=1 \
PREFIX='$(destdir)/usr' \
DOCINSTALLDIR='$$PREFIX/share/doc/libsenf-doc' \
INCLUDEINSTALLDIR='$$PREFIX/include/senf'
--- /dev/null
+## \file
+# \brief CopyToDir builder
+
+## \package senfscons.ProgramNoScan
+# \brief Program builder without target scanner
+#
+# This build is like env.Program() but does not scan for library dependencies.
+# This is needed if library dependencies are added explicitly, which is needed
+# when libraries are built in the same build and therefore might not exist
+# before builting the program (and will therefore not be found by the target
+# scanner)
+#
+# \ingroup builder
+
+import SCons.Builder, SCons.Defaults
+
+ProgramNoScan = SCons.Builder.Builder(action = SCons.Defaults.LinkAction,
+ emitter = '$PROGEMITTER',
+ prefix = '$PROGPREFIX',
+ suffix = '$PROGSUFFIX',
+ src_suffix = '$OBJSUFFIX',
+ src_builder = 'Object')
+
+def generate(env):
+ env['BUILDERS']['ProgramNoScan'] = ProgramNoScan
+
+def exists(env):
+ return 1
"Dia2Png",
"CopyToDir",
"InstallIncludes",
+ "ProgramNoScan",
]
opts = None
if type(testSources) is not type([]):
testSources = [ testSources ]
- installs = []
- installs.append( env.Install(dir, targets) )
+ installs = [ env.Install(dir, targets) ]
if not no_includes:
target = env.Dir(env['INCLUDEINSTALLDIR']).Dir(
if objects:
progEnv = env.Copy()
progEnv.Prepend(LIBS = LIBS)
- program = progEnv.Program(target=binary,source=objects+OBJECTS)
+ program = progEnv.ProgramNoScan(target=binary,source=objects+OBJECTS)
env.Default(program)
env.Depends(program, [ env.File(LibPath(x)) for x in LIBS ])
env.Alias('default', program)
def AllIncludesHH(env, headers):
headers.sort()
- file(env.File("all_includes.hh").abspath,"w").write("".join([ '#include "%s"\n' % f
- for f in headers ]))
- env.Alias('all', 'all_includes.hh')
- env.Clean('all', 'all_includes.hh')
-
+ target = env.File("all_includes.hh")
+ file(target.abspath,"w").write("".join([ '#include "%s"\n' % f
+ for f in headers ]))
+ env.Clean('all', target)