Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
senf
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package Registry
Container Registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Service Desk
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
wiback
senf
Commits
92278d25
Commit
92278d25
authored
17 years ago
by
g0dil
Browse files
Options
Downloads
Patches
Plain Diff
PPI Module and Connector documentation
parent
4c13f604
No related branches found
No related tags found
No related merge requests found
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
PPI/Connectors.hh
+316
-0
316 additions, 0 deletions
PPI/Connectors.hh
PPI/Doxyfile
+2
-0
2 additions, 0 deletions
PPI/Doxyfile
PPI/Mainpage.dox
+133
-64
133 additions, 64 deletions
PPI/Mainpage.dox
PPI/Module.hh
+142
-0
142 additions, 0 deletions
PPI/Module.hh
doclib/SConscript
+5
-1
5 additions, 1 deletion
doclib/SConscript
with
598 additions
and
65 deletions
PPI/Connectors.hh
0 → 100644
+
316
−
0
View file @
92278d25
// Copyright (C) 2007
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <g0dil@berlios.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.
/** \file
\brief Conenctors public header */
/** \defgroup connectors Connector classes
A connector has two independent properties
\li it may be \e active or \e passive
\li it may be an \e input or an \e output
\e Active connectors are activated from within the module, \e passive connectors are signaled by
the external framework. \e Input modules receive packets, \e output modules send packets.
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.
*/
#ifndef HH_Conenctors_
#define HH_Conenctors_ 1
// Custom includes
#include
<boost/utility.hpp>
//#include "Conenctors.mpp"
///////////////////////////////hh.p////////////////////////////////////////
namespace
senf
{
namespace
ppi
{
/** \brief Connector baseclass
This connector provides access to the generic connector facilities. This includes the
connection management (access to the connected peer) and the containment management (access
to the containing module)
*/
class
Connector
:
boost
::
noncopyable
{
public:
Connector
&
peer
();
///< Get peer connected to this connector
Module
&
module
();
///< Get this connectors containing module
protected:
// here to protect
Connector
();
~
Connector
();
};
/** \brief Passive connector baseclass
A passive connector is a connector which is activated externally whenever an I/O request
occurs. Passive connectors are the origin of throttling notifications. Depending on the type
of connector (output or input) the respective throttling is called forward or backward
throttling.
Passive connectors always handle two throttling states:
\li The \e native throttling state is set manually by the module. It is the throttling state
originating in the current module
\li The \e forwarded throttling state is the state as it is received by throttling
notifications
The accumulative throttling state is generated by combining all sub-states.
\ingroup connectors
*/
class
PassiveConnector
:
public
virtual
Connector
{
public:
template
<
class
Handler
>
void
onRequest
(
Handler
handler
);
///< Register I/O event handler
/**< The registered handler will be called, whenever packets
arrive or should be generated by the module depending
on the connector type (input or output). The \a handler
argument is either an arbitrary callable object or it
is a pointer-to-member to a member of the class which
holds this input. In the second case, the pointer will
automatically be bound to the containing instance.
\param[in] handler Handler to call, whenever an I/O
operation is to be performed. */
bool
throttled
();
///< Get accumulative throttling state
bool
nativeThrottled
();
///< Get native throttling state
void
throttle
();
///< Set native throttling
void
unthrottle
();
///< Revoke native throttling
void
notifyThrottle
();
///< Forward a throttling notification to this connector
void
notifyUnthrottle
();
///< Forward an unthrottling notification to this connector
ActiveConnector
&
peer
();
protected:
// here to protect
PassiveConnector
();
~
PassiveConnector
();
};
/** \brief Active connector baseclass
An active connector is a connector which emits I/O requests. Active connectors receive
throttling notifications. Depending on the type of connector (input or output) the
respective throttling is called forward or backward throttling.
Active connectors do not handle any throttling state, they just receive the
notifications. These notifications should then either be processed by the module or be
forwarded to other connectors.
\ingroup connectors
*/
class
ActiveConnector
:
public
virtual
Connector
{
public:
template
<
class
Handler
>
void
onThrottle
(
Handler
);
///< Register throttle notification handler
/**< The handler register here will be called, whenever a
throttle notification comes in. The \a handler argument
is either an arbitrary callable object or it is a
pointer-to-member to a member of the class which holds
this input. In the second case, the pointer will
automatically be bound to the containing instance.
\param[in] handler Handler to call on throttle
notifications. */
template
<
class
Handler
>
void
onUnthrottle
(
Handler
);
///< Register unthrottle notification handler
/**< The handler register here will be called, whenever an
unthrottle notification comes in. The \a handler
argument is either an arbitrary callable object or it
is a pointer-to-member to a member of the class which
holds this input. In the second case, the pointer will
automatically be bound to the containing instance.
\param[in] handler Handler to call on unthrottle
notifications. */
PassiveConnector
&
peer
();
protected:
// here to protect
PassiveConnector
();
~
PassiveConnector
();
};
/** \brief Input connector baseclass
An input connector receives packets. It may be either an ActiveConnector or a
PassiveConnector. An input connector contains a packet queue. This queue enables processing
packets in batches or generating multiple output packets from a single input packet. The
queues have the potential to greatly simplify the module implementations.
\ingroup connectors
*/
class
InputConnector
:
public
virtual
Connector
{
public:
typedef
unspecified
queue_iterator
;
///< Iterator type of the embedded queue
typedef
unspecified
size_type
;
///< Unsigned type representing the number of queue elements
Packet
::
ptr
operator
();
///< Get a packet
/**< This member is the primary method to access received
data. On passive connectors, this operator will just
dequeue a packet from the packet queue. If the
connector is active, the connector will request new
packets from the connected module. If the packet
request cannot be fulfilled, this is considered to be a
logic error in the module implementation and an
exception is raised. */
operator
unspecified_boolean_type
();
///< Check packet availability
/**< Using any input connector in a boolean context will
check, wether an input request can be fulfilled. This
is always possible if the queue is non-empty. If the
input is active, it also returns when the connected
passive output is not throttled so new packets can be
requested.
Calling the operator() member is an error if this test
returns \c false
\returns \c true if operator() can be called, \c false
otherwise */
operator
!
();
///< Check packet availability
/**< Inverse of the boolean conversion operator
\returns \c false if operator() can be called, \c true
otherwise */
OutputConnector
&
peer
();
queue_iterator
begin
();
///< Access queue begin (head)
queue_iterator
end
();
///< Access queue past-the-end (tail)
Packet
::
ptr
head
();
///< Return head element from the queue
size_type
queueSize
();
///< Return number of elements in the queue
bool
empty
();
///< Return queueSize() == 0
protected:
// here to protect
PassiveConnector
();
~
PassiveConnector
();
};
/** \brief Output connector baseclass
An output connector sends out packets. It may be either an ActiveConnector or a
PassiveConnector. An output connector does \e not have an built-in queueing, it relies on
the queueing of the connected input.
\ingroup connectors
*/
class
OutputConnector
:
public
virtual
Connector
{
public:
void
operator
(
Packet
::
ptr
);
///< Send out a packet
InputConnector
&
peer
();
protected:
// here to protect
PassiveConnector
();
~
PassiveConnector
();
};
/** \brief Combination of PassiveConnector and InputConnector
\ingroup connectors
*/
class
PassiveInput
:
public
PassiveConnector
,
public
InputConnector
{
public:
ActiveOutput
&
peer
();
template
<
class
QDisc
>
QDisc
const
&
qdisc
(
QDisc
const
&
disc
);
};
/** \brief Combination of PassiveConnector and OutputConnector
\ingroup connectors
*/
class
PassiveOutput
:
public
PassiveConnector
,
public
OutputConnector
{
public:
ActiveInput
&
peer
();
};
/** \brief Combination of ActiveConnector and InputConnector
\ingroup connectors
*/
class
ActiveInput
:
public
ActiveConnector
,
public
InputConnector
{
public:
void
request
();
///< request more packets without dequeing any packet
PassiveOutput
&
peer
();
};
/** \brief Combination of ActiveConnector and OutputConnector
\ingroup connectors
*/
class
ActiveOutput
:
public
ActiveConnector
,
public
OutputConnector
{
public:
ActiveInput
&
peer
();
};
}}
///////////////////////////////hh.e////////////////////////////////////////
//#include "Conenctors.cci"
//#include "Conenctors.ct"
//#include "Conenctors.cti"
#endif
// Local Variables:
// mode: c++
// fill-column: 100
// c-file-style: "senf"
// indent-tabs-mode: nil
// ispell-local-dictionary: "american"
// End:
This diff is collapsed.
Click to expand it.
PPI/Doxyfile
+
2
−
0
View file @
92278d25
...
...
@@ -2,3 +2,5 @@
PROJECT_NAME = libPPI
GENERATE_TAGFILE = doc/ppi.tag
TAGFILES = "$(TOPDIR)/Packets/doc/Packets.tag" "$(TOPDIR)/Socket/doc/Socket.tag"
This diff is collapsed.
Click to expand it.
PPI/Mainpage.dox
+
133
−
64
View file @
92278d25
...
...
@@ -28,12 +28,12 @@
The PPI concept is built around some key concepts
\li The PPI is based on processing \
e
packets. It does not handle stream oriented channels.
\li The PPI is built around reusable \
e
modules. Each module is completely independent.
\li Each module has an arbitrary number of \
e
connectors, inputs and outputs.
\li The modules are connected to each other using flexible \
e
connections.
\li Data flow throughout the network is governed via flexible automatic or manual \
e
throttling.
\li Modules may register additional external \
e
events (file descriptor events or timers).
\li The PPI is based on processing \
ref
packets. It does not handle stream oriented channels.
\li The PPI is built around reusable \
ref
modules. Each module is completely independent.
\li Each module has an arbitrary number of \
ref
connectors, inputs and outputs.
\li The modules are connected to each other using flexible \
ref
connections.
\li Data flow throughout the network is governed via flexible automatic or manual \
ref
throttling.
\li Modules may register additional external \
ref
events (file descriptor events or timers).
The PPI thereby builds on the facilities provided by the other components of the SENF
framework.
...
...
@@ -79,7 +79,8 @@
route(payload, output);
route(stuffing, output);
registerEvent(&RateStuffer::tick, IntervalTimer(1000u, packetsPerSecond));
registerEvent(&RateStuffer::tick,
senf::ppi::IntervalTimer(1000u, packetsPerSecond));
}
private:
...
...
@@ -134,7 +135,7 @@
This module just produces a copy of a given packet whenever output is requested.
\
sub
section connectors Connectors
\section connectors Connectors
Inputs and Outputs can be active and passive. An \e active I/O is <em>activated by the
module</em> to send data or to poll for available packets. A \e passive I/O is <em>signaled by
...
...
@@ -145,40 +146,40 @@
iteration. However, reading will only succeed, as long as packets are available from the
connection.
A module might want to queue incoming packets within a passive input or outgoing packets within
an active output. This is possible by either not reading any packet even though a new packet has
been scheduled on the input or by writing to the output while it is still throttled. To
facilitate this use, the connectors provide accessors to access the attached connection and it's
queue. This allows to analyze all packets available in the queue and act accordingly.
Since a module is free to generate more than a single packet on incoming packet requests, all
input connectors incorporate a packet queue. This queue is exposed to the module and allows the
module to process packets in batches.
\section connections Connections
To make use of the modules, they have to be instantiated and connections have to be created
between the I/O connectors. It is possible to connect any pair of input/output connectors as
long as at least one of them is active
Every connection contains an internal packet queue. Under normal operating conditions (without
throttling) the queue will mostly be empty since packets will be processed directly. If a
connection is throttled, it can still receive new packets on it's input which will then be
queued. This is necessary even though the throttling will be propagated backwards (so no new
packets should arrive) since a module may produce more then one result packet from a single
incoming packet.
long as one of them is active and the other is passive.
It is possible to connect two active connectors with each other using a special adaptor
module. This Module has a passive input and a passive output. It will queue any incoming packets
and automatically handle throttling events (see below). This adaptor is automatically added by
the connect method if needed.
To complete our simplified example: Lets say we have a <tt>
Udp
Input</tt>
module
and a
<tt>UdpOutput</tt> module. We can then use our <tt>RateStuffer</tt> module to build an
To complete our simplified example: Lets say we have a
n
<tt>
ActiveSocket
Input</tt> and a
<tt>
Passive
UdpOutput</tt> module. We can then use our <tt>RateStuffer</tt> module to build an
application which will create a fixed-rate UDP stream:
\code
RateStuffer rateStuffer (10);
CopyPacketGenerator generator (some_packet_ptr);
senf::Packet::ptr stuffingPacket = senf::Packet::create<...>(...);
CopyPacketGenerator generator (stuffingPacket);
senf::UDPv4ClientSocketHandle inputSocket (1111);
senf::ppi::SocketInput udpInput (inputSocket);
senf::ppi::ActiveSocketInput udpInput (inputSocket);
senf::UDPv4ClientSocketHandle outputSocket ("2.3.4.5:2222");
senf::ppi::SocketOutput udpOutput (outputSocket);
senf::ppi::
Passive
SocketOutput udpOutput (outputSocket);
senf::ppi::connect(udpInput.output, rateStuffer.payload
)
.bufferHighThresh(10
)
.bufferLowThresh(5
);
senf::ppi::connect(udpInput.output, rateStuffer.payload
,
dynamicModule<PassiveQueue>(
)
-> qdisc(ThresholdQueueing(10,5))
);
senf::ppi::connect(generator.output, rateStuffer.stuffing);
senf::ppi::connect(rateStuffer.output, udpOutput.input);
...
...
@@ -186,46 +187,39 @@
\endcode
First all necessary modules are created. Then the connections between these modules are set
up. The buffering o
f
the udpInput <-> rateStuffer
connection
is changed so the queue will begin
to
throttle only if more than 10 packets are in the queue. The connection will be unthrottled as
up. The buffering o
n
the udpInput <-> rateStuffer
adaptor
is changed so the queue will begin
to
throttle only if more than 10 packets are in the queue. The connection will be unthrottled as
soon as there are no more than 5 packets left in the queue. This application will read
udp-packts coming in on port 1111 and will forward them to port 2222 on host 2.3.4.5 with a
fixed rate of 10 packets / second.
fixed rate of 10 packets / second.
\section throttling Throttling
If a connection cannot pass packets in it's current state, the connection is \e throttled. In
simple cases, throttling is handled automatically by
\li the connection if the queue is exceeds the buffering threshold
\li I/O modules whenever the external source or sink of the module is not ready
Throttling is handled separately in each direction:
\li Forward throttling will throttle in the direction of the data flow. Example: No new packets
are available from an input. This will activate forward throttling until new data arrives
\li Backward throttling will throttle in the direction to the data source. Example: an output
device (e.g. serial interface) has no more room for data. This event will activate backward
throttling so no new data will arrive until the device can send data again
The throttling state is managed within the Connection. Automatic throttling utilizes the routing
information (provided in the modules constructor) to forward throttling events across
modules. However, automatic throttling can be disabled for each connector. Modules may also
register event handlers whenever a throttling event occurs.
Whenever a connection is throttled (in the corresponding direction), passive connectors will \e
not be called by the framework. This may lead to packets being accumulated in the connection
queue. These packets will be sent as soon as the connection is unthrottled. The unthrottle event
will hoewever only be forwarded when the queue is empty (or has reached it's lower buffering
threshold).
\code
passiveConnector.autoForwardThrottling(false);
passiveConnector.autoBackwardThrotttling(true);
passiveConnector.onForwardThrottle(...);
passiveConnector.onBackwardUnthrottle(...);
\endcode
Throttling is <em>not</em> enforced: especially a throttled output may still be called, the
excessive packets will be queued in the connection queue.
If a passive connector cannot handle incoming requests, this connector may be \e
throttled. Throttling a request will forward a throttle notification to the module connected
to that connector. The module then must handle this throttle notification. If automatic
throttling is enabled for the module (which is the default), the notification will automatically
be forwarded to all dependent connectors as taken from the flow information. For there it will
be forwarded to further modules and so on.
A throttle notification reaching an I/O module will normally disable the input/output by
disabling any external I/O events registered by the module. When the passive connector which
originated the notification becomes active again, it creates an unthrottle notification which
will be forwarded in the same way. This notification will re-enable any registered I/O events.
The above discussion shows, that throttle events are always generated on passive connectors and
received on active connectors. To differentiate further, the throttling originating from a
passive input is called <em>backward throttling</em> since it is forwarded in the direction \e
opposite to the data flow. Backward throttling notifications are sent towards the input
modules. On the other hand, the throttling originating from a passive output is called
<em>forward throttling</em> since it is forwarded along the \e same direction the data
is. Forward throttling notifications are therefore sent towards the output modules.
Since throttling a passive input may not disable all further packet delivery immediately, any
passive input contains an input queue. In it's default configuration, the queue will send out
throttle notifications when it becomes non-empty and unthrottle notifications when it becomes
empty again. This automatic behavior may however be disabled. This allows a module to collect
incoming packets in it's input queue before processing a bunch of them in one go.
\section events Events
...
...
@@ -233,6 +227,81 @@
the PPI framework. Possible event sources are
\li time based events
\li file descriptors.
Here some example code implementing the ActiveSocketInput Module:
\code
class ActiveSocketInput
: public senf::ppi::Module
{
static PacketParser<senf::DataPacket> defaultParser_;
public:
ActiveOutput output;
typedef senf::ClientSocketHandle<
senf::MakeSocketPolicy< senf::ReadablePolicy,
senf::DatagramFramingPolicy > > Socket;
// I hestitate taking parser by const & since a const & can be bound to
// a temporary even though a const & is all we need. The real implementation
// will probably make this a template arg. This simplifies the memory management
// from the users pov.
ActiveSocketInput(Socket socket, DataParser & parser = SocketInput::defaultParser_)
: socket_ (socket),
parser_ (parser)
event_ (registerEvent( &ActiveSocketInput::data,
senf::ppi::IOSignaler(socket, senf::ppi::IOSignaler::Read) ))
{
route(event_, output);
}
private:
Socket socket_;
DataParser const & parser_;
senf::ppi:IOSignaler::EventBinding event_;
void data()
{
std::string data;
socket_.read(data);
output(parser_(data));
}
};
\endcode
First we declare our own socket handle type which allows us to read packets. The constructor
then takes two arguments: A compatible socket and a parser object. This parser object gets
passed the packet data as read from the socket (an \c std::string) and returns a
senf::Packet::ptr. The \c PacketParser is a simple parser which interprets the data as specified
by the template argument.
We register an IOSignaler event. This event will be signaled whenever the socket is
readable. This event is routet to the output. This routing automates throttling for the socket:
Whenever the output receives a throttle notifications, the event will be temporarily disabled.
Processing arriving packets happens in the \c data() member: This member simple reads a packet
from the socket. It passes this packet to the \c parser_ and sends the generated packet out.
\implementation Generation of throttle notifications: Backward throttling notifications are
automatically generated (if this is not disabled) whenever the input queue is non-empty \e
after the event handler has finished processing. Forward throttling notifications are not
generated automatically within the connector. However, the Passive-Passive adaptor will
generate Forward-throttling notifications whenever the input queue is empty.
\note Open Issues
\li We need to clearly differentiate between auto-throttling and auto-throttle-forwarding,
between a connectors own throttling state and the forwarded state.
\li Exception handling
\li ActiveInputs also need a queue: This is necessary to allow a PassiveOutput to create more
than a single packet from a single 'onRequest' event. This greatly simplifies writing
modules which produce multiple output packets for a single input packet.
\li We need to clear up the throttled() member semantics: If the connector is throttled, does
it return so if there are still packets in the queue? Probably yes. However, it does not
forward throttling notifications until instructed by the qdisc. Throttling notifications are
also bound to onThrottle/onUnThrottle callbacks. The semantics are then clear: An active
connector emitting onThrottle cannot process any further request (for inputs, no data will
be available, for outputs the data will be queued in the peer input)
*/
...
...
This diff is collapsed.
Click to expand it.
PPI/Module.hh
0 → 100644
+
142
−
0
View file @
92278d25
// Copyright (C) 2007
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <g0dil@berlios.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.
/** \file
\brief Module public header */
#ifndef HH_Module_
#define HH_Module_ 1
// Custom includes
#include
<boost/utility.hpp>
//#include "Module.mpp"
///////////////////////////////hh.p////////////////////////////////////////
namespace
senf
{
namespace
ppi
{
/** \brief Module baseclass
senf::ppi::Module is the baseclass of all PPI modules. It provides the module implementation
with interfaces to several PPI facilities:
\li Connector management
\li Flow management
\li Event handling
To provide internal bookkeeping, most access to the PPI infrastructure is managed through
this base class.
Instances of this class may be allocated either statically or dynamically. Dynamic instances
are automatically managed using the dynamicModule adaptor.
*/
class
Module
:
boost
::
noncopyable
{
protected:
Module
();
~
Module
();
template
<
class
Source
,
class
Target
>
Route
route
(
Source
const
&
source
,
Target
const
&
target
);
///< Define flow information
/**< Using the route() and noroute() members, the
information flow within the module is defined. Routing
may be specified either between inputs, outputs and
events. The routing information is used to perform
automatic throttling. The throttling behavior may
however be controlled manually.
Even if no automatic throttling is desired <em>it is
vital to define the flow information for all inputs and
outputs</em>. Without flow information important
internal state of the module cannot be
initialized. This includes, explicitly defining
terminal inputs and outputs using noroute. Event
routing however is optional.
The return value may be used to alter routing
parameters like throttling parameters.
\param[in] source Data source, object which controlls
incoming data
\param[in] target Data target, object which controlls
outgoing data
\returns Route instance describing this route */
template
<
class
Connector
>
void
noroute
(
Connector
const
&
connector
);
///<Define terminal connectors
/**<
The noroute() member explicitly declares, that a
connector is terminal and does not directly
receive/forward data from/to some other
connector. <em>It is mandatory to define routing
information for terminal connectors</em>.
See the route() documentation for more on routing
\param[in] connector Terminal connector to declare */
template
<
class
Target
,
class
Descriptor
>
typename
Descriptor
::
EventBinding
const
registerEvent
(
Target
target
,
Descriptor
const
&
descriptor
);
///< Register an external event
/**< The \a target argument may be either an arbitrary
callable object or it may be a member function pointer
pointing to a member function of the Module derived
classed. The handler may \e optionally take an Argument
of type <tt>typename Descriptor::Event const
&</tt>. This object allows to access detailed
information on the event delivered.
The \a descriptor describes the event to signal. This
may be a timer event or some type of I/O event on a
file descriptor or socket.
The return value may be used to modify the
binding. This allows to temporarily inhibit event
delivery or to remove the binding explicitly. Depending
on the type of event, other operations may be
possible. See the event descriptor documentation.
\param[in] target The handler to call whenever the event
is signaled
\param[in] descriptor The type of event to register
\returns An event binding instance of the appropriate
type. */
};
}}
///////////////////////////////hh.e////////////////////////////////////////
//#include "Module.cci"
//#include "Module.ct"
//#include "Module.cti"
#endif
// Local Variables:
// mode: c++
// fill-column: 100
// c-file-style: "senf"
// indent-tabs-mode: nil
// ispell-local-dictionary: "american"
// End:
This diff is collapsed.
Click to expand it.
doclib/SConscript
+
5
−
1
View file @
92278d25
...
...
@@ -118,7 +118,11 @@ env.Alias('all_docs',
env
.
Command
(
'
search.php
'
,
'
html-munge.xsl
'
,
[
writeTemplate
,
'
xsltproc --nonet --html --stringparam topdir .. -o - $SOURCE $TARGET 2>/dev/null
'
+
r
'
| sed -e
"
s/\[\[/<?/g
"
-e
"
s/\]\]/?>/g
"
> ${TARGET}.tmp
'
,
+
"
| sed
"
+
r
"
-e
'
s/\[\[/<?/g
'
-e
'
s/\]\]/?>/g
'"
+
r
"
-e
'
s/\$$projectname/Overview/g
'"
+
r
"
-e
'
s/\$$title/Search results/g
'"
+
"
> ${TARGET}.tmp
"
,
'
mv ${TARGET}.tmp ${TARGET}
'
],
TEMPLATE
=
Literal
(
HEADER
+
OVERVIEW_EXTRA_HEADER
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment