X-Git-Url: http://g0dil.de/git?a=blobdiff_plain;f=Socket%2FSocketPolicy.hh;h=6ef298149ccb7ce657f3eef5993829e0523d1d93;hb=983ae64545d03ca24e7c5cb2c9ed2749435844eb;hp=eb453aff28e7a4ae32fdebed4b8468ab7a66e77a;hpb=ac88c68bb3aebad5f7d91ce44f1c845d973f9613;p=senf.git diff --git a/Socket/SocketPolicy.hh b/Socket/SocketPolicy.hh index eb453af..6ef2981 100644 --- a/Socket/SocketPolicy.hh +++ b/Socket/SocketPolicy.hh @@ -1,6 +1,6 @@ // $Id$ // -// Copyright (C) 2006 +// Copyright (C) 2006 // Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS) // Kompetenzzentrum fuer Satelitenkommunikation (SatCom) // Stefan Bund @@ -12,7 +12,7 @@ // // 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 +// 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 @@ -24,12 +24,20 @@ \brief Policy Framework public header \todo We should probably remove BufferingPolicy from the - interface, it does not make much sense (how did I come to include - it ??) - + interface, it does not make much sense (how did I come to + include it ??) + \todo Do we want to support separate read and write policies. This - allows to treat pipes within this framework however, is this worth - the effort? + allows to treat pipes within this framework however, is this + worth the effort? + + \idea Creating a new Socket will create 4 (!) new instances (The + handle, the body, the policy and the protocol) of which 3 + (argh) (body, policy and protocol) live on the heap. This is + expensive. We should convert all the policy classes to + singletons and assign the same instance to all socket bodies + with the same policy. This would reduce the number of heap + allocations per socket handle to two. */ /** \defgroup policy_group The Policy Framework @@ -44,38 +52,42 @@ minimal functionality. All further functionality is relayed to a policy class, or more precisely, to a group of policy classes, one for each policy axis. The policy axis are - +
addressingPolicy
configures, whether a socket is addressable and if so, configures the address type
- +
framingPolicy
configures the type of framing the socket provides: either no framing providing a simple i/o stream or packet framing
- +
communicationPolicy
configures,if and how the communication partner is - selected
- + selected +
readPolicy
configures the readability of the socket
- +
writePolicy
configures the writability of the socket
- +
bufferingPolicy
configures, if and how buffering is configured for a socket
- Every Policy value is identified by a class type. The policy - classes themselves built an inheritance hierarchy for each policy - axis. For each policy axis, the root of this tree is the class - named \i Policy \c Base (e.g. \p AddressingPolicyBase). - - The senf::SocketPolicy defines the complete policy of a socket. It + In a concrete policy, each of these policy axis is assigned a value, + the policy value. This value is identified by a class type. For example, + possible values for framingPolicy are DatagramFramingPolicy + or StreamFramingPolicy which are classes derived from the axis + base class FramingPolicyBase. This base class doubles as + UnspecifiedFramingPolicy (which is just a typedef alias). + If a policy axis is assigned this Unspecified type, the axis is left + unspecified, the policy will be incomplete. + + The senf::SocketPolicy tempalte defines the complete policy of a socket. It combines a set of policy classes, one for each policy - axis. Together, they define the behavior of a socket handle. The + axis as described above. Together, they define the behavior of a socket handle. The socket handle instances do not implement any socket functionality themselves instead defering the implementation to the policy classes. The SocketHandle interface is therefore \e not @@ -91,21 +103,26 @@ Two SocketHandle's with different policies can be \e compatible. If they are, the more derived SocketHandle can be converted (assigned to) the more basic SocketHandle. - + + \doc Example (concrete policy, incomplete policy, compatibility/assignment) + \section policy_group_details The Policy Framework Classes + \doc Policy should be Axis here. Make clear, that this information is only + needed when extending the library. + In the following discussion we will use the following conventions: \li \e Policy is one or \c AddressingPolicy, \c FramingPolicy, \c - CommunicationPolicy, \c ReadPolicy, \c WritePolicy or \c - BufferingPolicy + CommunicationPolicy, \c ReadPolicy, \c WritePolicy or \c + BufferingPolicy \li \e socketPolicy is any socket policy (that is, an - instantiation of the SocketPolicy template) + instantiation of the SocketPolicy template) \li \e trait is an any policy class (that is, any class derived - from one of the axis base classes) + from one of the axis base classes) Each axis is comprised of a number of classes and templates (all in namespace senf of course): - +
\e Policy \c Base (ex: AddressingPolicyBase)
Baseclass of all policies in this axis
@@ -124,7 +141,7 @@
\c If \e Policy \c IsNot < \e socketPolicy, \e trait > (ex: IfAddressingPolicyIsNot)
The inverse of above
- + These classes form the basis of the policy framework. To bind the policy axis together, there are some more classes and templates. @@ -135,7 +152,9 @@ checking, that it derives from SocketPolicyBase. This is simpler than chacking the template directly). -
\c template \c SocketPolicy < \e addressingPolicy, \e framingPolicy, \e communicationPolicy, \e readPolicy, \e writePolicy, \e bufferingPolicy >
+
\c template \c SocketPolicy < \e addressingPolicy, \e + framingPolicy, \e communicationPolicy, \e readPolicy, \e + writePolicy, \e bufferingPolicy >
This is the central SocketPolicy template. It combines a complete set of policy classes, one for each axis.
@@ -181,7 +200,7 @@ specify the call signature not the way, the member must be defined (FileHandle really is not a FileHandle but an arbitrary SocketHandle). - + If the existence of a member depends on other policies, you should use the IfSomePolicyIs and IfSomePolicyIsNot templates to @@ -189,12 +208,12 @@ policy: \code - struct ExampleAddressingPolicy + struct ExampleAddressingPolicy { - template - void connect(senf::SocketHandle handle, Address & addr, - typename senf::IfCommmunicationPolicyIs< - Policy, senf::ConnectedCommunicationPolicy>::type * = 0); + template + void connect(senf::SocketHandle handle, Address & addr, + typename senf::IfCommmunicationPolicyIs< + Policy, senf::ConnectedCommunicationPolicy>::type * = 0); }; \endcode @@ -206,8 +225,7 @@ senf::ConnectedCommunicationPolicyIs is based on the \c boost::enable_if template). - \see \ref policy_framework \n - \ref extend_policy \n + \see \ref extend_policy \n The Boost enable_if utility \n The Boost.MPL library \n The Boost.Preprocessor library @@ -219,6 +237,14 @@ with \c SocketPolicyIsBaseOf. */ +/** \defgroup policy_impl_group Policy Implementation classes + \ingroup policy_group + + Here you will find all policy classes. Also included are some + supporting classes which are used as base classes to build other + policy classes. + */ + #ifndef HH_SocketPolicy_ #define HH_SocketPolicy_ 1 @@ -239,162 +265,162 @@ namespace senf { // be adjusted accordingly) /** \brief List all policy axis - - \internal - This define symbol is used to configure the policy axis. The - base class for each of these axis must be defined explicitly - (e.g. AddressingPolicyBase). The implementation files will - then automatically generate all the other classes from this - list. + \internal - \see policy_group + This define symbol is used to configure the policy axis. The + base class for each of these axis must be defined explicitly + (e.g. AddressingPolicyBase). The implementation files will + then automatically generate all the other classes from this + list. + + \see policy_group */ -# define SENF_SOCKET_POLICIES \ - (AddressingPolicy) \ - (FramingPolicy) \ - (CommunicationPolicy) \ - (ReadPolicy) \ - (WritePolicy) \ - (BufferingPolicy) +# define SENF_SOCKET_POLICIES \ + (AddressingPolicy) \ + (FramingPolicy) \ + (CommunicationPolicy) \ + (ReadPolicy) \ + (WritePolicy) \ + (BufferingPolicy) // Wer define these classes explicitly (and not with some macro // magic) because // a) AddressingPolicyBase is different from all the others // b) We want to document each one explicitly - + /** \brief Policy defining socket addressing - AddressingPolicyBase is the baseclass of all addressing policy - classes. When defining a new addressing policy, the following - members can be defined. All methods must be static. + AddressingPolicyBase is the baseclass of all addressing policy + classes. When defining a new addressing policy, the following + members can be defined. All methods must be static. - - - - - - -
typedef Address Address type
method void local(FileHandle, Address &) Get local socket address
method void peer(FileHandle, Address &) Get remote socket address
method void bind(FileHandle, Address const &) Bind socket to local address
method
void connect(FileHandle, Address const &) Connect to remote address
+ + + + + + +
typedef Address Address type
method void local(FileHandle, Address &) Get local socket address
method void peer(FileHandle, Address &) Get remote socket address
method void bind(FileHandle, Address const &) Bind socket to local address
method
void connect(FileHandle, Address const &) Connect to remote address
- \see policy_group + \see policy_group */ struct AddressingPolicyBase { - virtual ~AddressingPolicyBase() {} - - typedef GenericSockAddr Address; + virtual ~AddressingPolicyBase() {} + + typedef GenericSockAddr Address; }; /** \brief Policy defining the framing format - This policy does not define any operations since it does have - no influence on any method signature. It does however affect - the semantics of the \c read() and \c write() operations. + This policy does not define any operations since it does have + no influence on any method signature. It does however affect + the semantics of the \c read() and \c write() operations. - \note This policy axis probably only has two sensible statess: - StreamFramingPolicy and DatagramFramingPolicy. + \note This policy axis probably only has two sensible statess: + StreamFramingPolicy and DatagramFramingPolicy. - \see policy_group + \see policy_group */ - struct FramingPolicyBase + struct FramingPolicyBase { - virtual ~FramingPolicyBase() {} + virtual ~FramingPolicyBase() {} }; /** \brief Policy defining, how peers are selected - The CommunicationPolicy may define two members: - - - - -
method void listen(FileHandle, unsigned backlog) Switch socket into listening state
method int accept(FileHandle, Address &) Accept a new connection
- - The \c listen member is straight forward. The \c accept() member - must return a new file descriptor (which will be used to - create a new SocketHandle of the correct type). Additionally, - accept() should only be defined, if the Addressing policy is - not \c NoAddressingPolicy (which together with - ConnectedCommunicationPolicy would identify a point-to-point - link with fixed communication partners). - - \note This Policy only has two meaningful states: - ConnectedCommunicationPolicy and - UnconnectedCommunicationPolicy. It is probably not sensible to - define a new CommunicationPolicy type. - - \see policy_group + The CommunicationPolicy may define two members: + + + + +
method void listen(FileHandle, unsigned backlog) Switch socket into listening state
method int accept(FileHandle, Address &) Accept a new connection
+ + The \c listen member is straight forward. The \c accept() member + must return a new file descriptor (which will be used to + create a new SocketHandle of the correct type). Additionally, + accept() should only be defined, if the Addressing policy is + not \c NoAddressingPolicy (which together with + ConnectedCommunicationPolicy would identify a point-to-point + link with fixed communication partners). + + \note This Policy only has two meaningful states: + ConnectedCommunicationPolicy and + UnconnectedCommunicationPolicy. It is probably not sensible to + define a new CommunicationPolicy type. + + \see policy_group */ struct CommunicationPolicyBase { - virtual ~CommunicationPolicyBase() {} + virtual ~CommunicationPolicyBase() {} }; /** \brief Policy defining the readability - The ReadPolicy defines, wether the socket is readable. It - may define two members: + The ReadPolicy defines, wether the socket is readable. It + may define two members: - - - -
method unsigned read(FileHandle, char * buffer, unsigned size) read data from socket
method unsigned readfrom(FileHandle, char * buffer, unsigned size, Address &) read data from unconnected socket
+ + + +
method unsigned read(FileHandle, char * buffer, unsigned size) read data from socket
method unsigned readfrom(FileHandle, char * buffer, unsigned size, Address &) read data from unconnected socket
- The second member should only be enabled if the communication - policy is UnconnectedCommunication (otherwise it does not make - sense since the communication partner is fixed) (see - AddressingPolicyBase on how to do this). + The second member should only be enabled if the communication + policy is UnconnectedCommunication (otherwise it does not make + sense since the communication partner is fixed) (see + AddressingPolicyBase on how to do this). - \note This Policy only has two meaningful states: - ReadablePolicy and NotReadablePolicy. It probably does not - make sense to define new read policy types. + \note This Policy only has two meaningful states: + ReadablePolicy and NotReadablePolicy. It probably does not + make sense to define new read policy types. - \see policy_group + \see policy_group */ struct ReadPolicyBase { - virtual ~ReadPolicyBase() {} + virtual ~ReadPolicyBase() {} }; /** \brief Policy defining the writability - The WritePolicy defines, wether the socket is writable. It may - define two members: + The WritePolicy defines, wether the socket is writable. It may + define two members: - - - -
method unsigned write(FileHandle, char * buffer, unsigned size) read data from socket
method unsigned writeto(FileHandle, char * buffer, unsigned size, Address &) read data from unconnected socket
+ + + +
method unsigned write(FileHandle, char * buffer, unsigned size) read data from socket
method unsigned writeto(FileHandle, char * buffer, unsigned size, Address &) read data from unconnected socket
- The second member should only be enabled if the communication - policy is UnconnectedCommunication (otherwise it does not make - sense since the communication partner is fixed) (see - AddressingPolicyBase on how to do this). + The second member should only be enabled if the communication + policy is UnconnectedCommunication (otherwise it does not make + sense since the communication partner is fixed) (see + AddressingPolicyBase on how to do this). - \note This Policy only has two meaningful states: - WritablePolicy and NotWritablePolicy. It probably does not - make sense to define new write policy types. + \note This Policy only has two meaningful states: + WritablePolicy and NotWritablePolicy. It probably does not + make sense to define new write policy types. - \see policy_group + \see policy_group */ struct WritePolicyBase { - virtual ~WritePolicyBase() {} + virtual ~WritePolicyBase() {} }; - + /** \brief Policy defining the buffering interface - The BufferingPolicy defines the buffer handling of the - socket. It may provide the follogin members: - - \see policy_group + The BufferingPolicy defines the buffer handling of the + socket. It may provide the follogin members: + + \see policy_group */ struct BufferingPolicyBase { - virtual ~BufferingPolicyBase() {} + virtual ~BufferingPolicyBase() {} }; - + // The implementation file will for each Policy declared above // define the following (SomePolicy is one of the above): // @@ -416,19 +442,19 @@ namespace senf { // The following stub definitions are only visible to doxygen /** \brief Alias of AddressingPolicyBase for better readability - \see \ref policy_group + \see \ref policy_group */ typedef AddressingPolicyBase UnspecifiedAddressingPolicy; - + /** \brief Check single policy axis - - This template is an example of the \i Policy \c Is family of - tempalte metafunctions. It will check, wether \c Trait is a - valid compatible Policy class of \c SocketPolicy. \c Trait - must be derived from AddressingPolicyBase (respectively \i - Policy \c Base). - - \see \ref policy_group + + This template is an example of the \e Policy \c Is family of + tempalte metafunctions. It will check, wether \c Trait is a + valid compatible Policy class of \c SocketPolicy. \c Trait + must be derived from AddressingPolicyBase (respectively \i + Policy \c Base). + + \see \ref policy_group */ template struct AddressingPolicyIs @@ -436,21 +462,21 @@ namespace senf { /** \brief Enable template overload depending on policy value - This template is an exmaple of the \c If \i Policy \c Is - family of templates. It is used like Boost.enable_if - to enable a templated overload only, if the AddressingPolicy - of \i Policy is compatible with \c Trait (that is the - AddressingPolicy of \c Policy is derived from \c Trait). + This template is an exmaple of the \c If \e Policy \c Is + family of templates. It is used like Boost.enable_if + to enable a templated overload only, if the AddressingPolicy + of \e Policy is compatible with \c Trait (that is the + AddressingPolicy of \c Policy is derived from \c Trait). - \see policy_group + \see policy_group */ template struct IfAddressingPolicyIs {}; /** \brief Inversion of \c IfAddressingPolicyIs - \see policy_group + \see policy_group */ template struct IfAddressingPolicyIsNot @@ -458,50 +484,75 @@ namespace senf { /** \brief Baseclass of all SocketPolicies - \internal + \internal - This class is used to + This class provides the baseclass of all socket policies + (bundles). It serves two purposes: + \li It allows us to easily identify a socket policy bundle by + checking a classes baseclass. + \li It provides an abstract (virtual) interface to access the + policy axes - \see policy_group + \see policy_group */ struct SocketPolicyBase - {}; + { + /** \brief Polymorphic access to policy axes + + This is an example of a policy axes accessor. It returns a + reference to the policy axes used by the conrecte protocol + bundle. This reference can then be checked using RTTI + information. + */ + AddressingPolicyBase const & theAddressingPolicy() const = 0; + }; /** \brief Collection of policy classes - - The SocketPolicy template defines the complete Policy used by - the socket library. It contains one policy class for each - policy axis. - - A SocketPolicy can be complete or incomplete. An incomplete - SocketPolicy will have at least one axis set to \c Undefined - \i Policy (or a generic derived class which is used to group - some other policies but does not (completely) define the - policy behavior). A complete SocketPolicy will have a - concrete definition of the desired behavior for each policy - axis. - - \see policy_group + + The SocketPolicy template defines the complete Policy used by + the socket library. It contains one policy class for each + policy axis. This template takes one policy from each axis as + it's template arguments (this example implementation only has + AddressingPolicy as an argument). + + A SocketPolicy can be complete or incomplete. An incomplete + SocketPolicy will have at least one axis set to \c Undefined + \e Policy (or a generic derived class which is used to group + some other policies but does not (completely) define the + policy behavior). A complete SocketPolicy will have a + concrete definition of the desired behavior for each policy + axis. + + \see policy_group */ - template < - class AddressingPolicy, - class FramingPolicy, - class CommunicationPolicy, - class ReadPolicy, - class WritePolicy, - class BufferingPolicy > + template < class AddressingPolicy > struct SocketPolicy - {}; - + { + /** \brief Check dynamic policy compatibility + + This method will check the socket policy \a other against + this policy. It will check, wether \a other is a base + policy (or the same) of this policy. This check is done + against the \e dynamic type of \a other using RTTI. It + will throw \c std::bad_cast, if the policy is not + compatible. + + \param[in] other SocketPolicy to check + \throws std::bad_cast if \a other is not a compatible + policy + */ + static void checkBaseOf(SocketPolicyBase const & other); + }; + /** \brief Metafunction to create SocketPolicy - - This template metafunction simplifies the creation of a - SocketPolicy instantiation. It takes any number (that is up to - 6) of Policy classes as arguments in any Order. It will create - a SocketPolicy from these policy classes. Any axis not - specified will be left as \c Unspecified \i Policy. - - \see policy_group + + This template metafunction simplifies the creation of a + SocketPolicy instantiation. It takes any number (that is up to + 6) of Policy classes as arguments in any Order. It will create + a SocketPolicy from these policy classes. Any axis not + specified will be left as \c Unspecified \e Policy. + + \see policy_group */ template struct MakeSocketPolicy @@ -509,19 +560,19 @@ namespace senf { /** \brief Check policy compatibility - This tempalte metafunction checks, wether the SocketPolicy \c - Derived is more specialized than \c Base (and therefore a - SocketHandle with policy \c Derived is convertible to a - SocketHandle with policy \c Base). + This tempalte metafunction checks, wether the SocketPolicy \c + Derived is more specialized than \c Base (and therefore a + SocketHandle with policy \c Derived is convertible to a + SocketHandle with policy \c Base). - The metafunction will return true (that is inherits from \c - boost::true_type, see the Boost.MPL - library documentation for more information) if each policy - class in \c Base is a baseclass of (or the same as) the - corresponding policy class in \c Derived. + The metafunction will return true (that is inherits from \c + boost::true_type, see the Boost.MPL + library documentation for more information) if each policy + class in \c Base is a baseclass of (or the same as) the + corresponding policy class in \c Derived. - \see policy_group + \see policy_group */ template struct SocketPolicyIsBaseOf @@ -542,5 +593,8 @@ namespace senf { // Local Variables: // mode: c++ +// fill-column: 100 // c-file-style: "senf" +// indent-tabs-mode: nil +// ispell-local-dictionary: "american" // End: