1 // ANNA - Anna is Not Nothingness Anymore
3 // (c) Copyright 2005-2014 Eduardo Ramos Testillano & Francisco Ruiz Rayo
5 // http://redmine.teslayout.com/projects/anna-suite
7 // Redistribution and use in source and binary forms, with or without
8 // modification, are permitted provided that the following conditions
11 // * Redistributions of source code must retain the above copyright
12 // notice, this list of conditions and the following disclaimer.
13 // * Redistributions in binary form must reproduce the above
14 // copyright notice, this list of conditions and the following disclaimer
15 // in the documentation and/or other materials provided with the
17 // * Neither the name of the copyright holder nor the names of its
18 // contributors may be used to endorse or promote products derived from
19 // this software without specific prior written permission.
21 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 // Authors: eduardo.ramos.testillano@gmail.com
34 // cisco.tierra@gmail.com
37 #ifndef anna_comm_Handler_hpp
38 #define anna_comm_Handler_hpp
40 #include <netinet/in.h>
42 #include <anna/core/mt/Runnable.hpp>
43 #include <anna/core/util/Millisecond.hpp>
44 #include <anna/core/util/Microsecond.hpp>
59 Controlador de comunicaciones generico.
61 class Handler : public Runnable {
63 using Runnable::initialize;
65 using Runnable::setIsRunning;
68 Mascara que define el funcionamiento de los manejadores de mensajes.
70 struct Support { enum _v { None = 0, CongestionControl = 1 }; };
73 Tipo de controladores predefinidos.
77 ServerSocket, /**< Controlador para ServerSocket */
78 LocalConnection, /**< Controlador para LocalConnection */
79 RemoteConnection, /**< Controlador para RemoteConnection */
80 DatagramSocket, /**< Controlador para DatagramSocket */
81 BinderSocket, /**< Controlador para comm::BinderSocket usado para compartir direcciones IPs. */
82 Custom, /**< Controlador definido por el usuario */
83 ClientSocket /**< Controlador para un ClientSocket directo (sin uso intermedio de Server */
88 Devuelve el tipo de controlador.
89 \return el tipo de controlador.
91 Type::_v getType() const throw() { return a_type; }
94 Devuelve el descriptor de fichero asociado a este controlador.
95 \return el descriptor de fichero asociado a este controlador.
97 int getfd() const throw() { return a_fd; }
100 Devuelve \em true si el descriptor de fichero asociado a este controlador soporta
101 control de congestion o \em false en otro caso.
102 \return \em true si el descriptor de fichero asociado a este controlador soporta
103 control de congestion o \em false en otro caso.
105 bool supportCongestionControl() const throw() { return (a_support & Support::CongestionControl) != 0; }
108 Devuelve \em true si este manejador soporta control de temporizacion o \em false en otro
110 \return \em true si este manejador soporta control de temporizacion o \em false en otro
113 bool supportTimeout() const throw() { return a_timeout > 0; }
116 Operador de comparacion.
117 \param fd Descriptor de fichero con el que comparar.
118 \return \em true si el fd recibido es igual al establecido con #setfd o \em false en caso contrario.
120 bool operator == (const int fd) const throw() { return a_fd == fd; }
123 Metodo invocado por el comunicador cuando detectado actividad en el descriptor de
124 fichero asociado a este controlador.
126 virtual void apply() throw(RuntimeException) = 0;
129 Devuelve el ClientSocket asociado a este manejador de conexiones.
130 \return El ClientSocket asociado a este manejador de conexiones. Puede ser NULL.
131 \warning Uso interno. Se necesita para poder cooperar con el anna::comm::CongestionController.
133 virtual ClientSocket* getClientSocket() throw() { return NULL; }
136 Devuelve una cadena con la informacion referente a esta instancia.
137 \return una cadena con la informacion referente a esta instancia.
139 virtual std::string asString() const throw();
142 Devuelve un documento XML con la informacion referente a esta instancia.
143 \return un documento XML con la informacion referente a esta instancia.
145 virtual xml::Node* asXML(xml::Node* parent) const throw(RuntimeException);
148 Amplia la informacion XML del nodo recibido como parametro.
149 \param node Nodo XML en el que incorporar los atributos.
151 void asAttribute(xml::Node* node) const throw(RuntimeException);
155 Instancia del comunicador puede ser NULL.
157 Communicator* a_communicator;
161 \param communicator Comunicador asociado a este controlador.
162 \param type Tipo de Comunicador.
163 \param support Una combinacion de los valores de Handler::Support.
165 Handler(Communicator* communicator, const Type::_v type, const int support = Support::CongestionControl) :
166 a_communicator(communicator),
177 \param type Tipo de Comunicador.
178 \param support Una combinacion de los valores de Handler::Support.
180 Handler(const Type::_v type, const int support = Support::CongestionControl) :
181 a_communicator(NULL),
191 Establecer el descriptor de fichero asociado a este controlador.
192 \param fd Descriptor de fichero asociado a este controlador.
193 \warning La implementacion del metodo initialize debe invocar a este metodo
194 con descriptor de fichero valido.
196 void setfd(const int fd) throw() { setId(anna::functions::asText("Handler", a_fd = fd)); }
199 Establece el numero de milisegundos maximo que puede estar este manejador sin
200 recibir mensajes antes de ser cerrado por el nucleo.
201 \param timeout Numero de milisegundos maximo sin recibir mensajes.
203 void setTimeout(const Millisecond &timeout) throw() {
205 a_maxTime = functions::hardwareClock() + a_timeout;
209 En los manejadores que pueden recibir mas de una peticion en cada llamada a apply este
210 metodo debe ser invocado para saber si debe dejar de procesar mensajes.
212 bool canContinue() const throw() { return hasRequestedStop() == false; }
215 Metodo con el que podemos redefinir el comportamiento cuando recibe la notificacion de
216 que una IP ha dejado de estar disponible.
217 \param address Direccion IP que ha dejado de estar disponible.
218 \warning Se invoca automaticamente desde el comunicador.
220 virtual void breakAddress(const in_addr_t& address) throw() {;}
223 Metodo con el que podemos redefinir el comportamiento cuando recibe la notificacion de
224 que una IP esta disponible.
225 \param address Direccion IP que ha pasado a estar disponible.
226 \warning Se invoca automaticamente desde el comunicador.
228 virtual void recoverAddress(const in_addr_t& address) throw() {;}
231 * Método que se invoca periódicamente para comprobar si tenemos pendiente el cierre de la conexión
232 * con el canal asociado a este manejador, cuando el fd asociado al manejador de recibe actividad.
234 * \return \em true Si termina la conexión o \em false en otro caso.
236 virtual bool testClose() throw(RuntimeException) { return false;}
239 Metodo con el que podemos redefinir el comportamiento cuando recibe la notificacion de
240 que el componente asociado a este controlador ha dejado de estar operativo.
241 \warning Se invoca automaticamente desde el comunicador al invocar al metodo
242 \em detach correspondiente.
244 virtual void finalize() throw() {;}
247 * Metodo con el que podemos redefinir el comportamiento cuando recibe la notificacion de
248 * que el componente asociado a este controlador ha sido duplicado en un proceso hijo.
249 * \warning Exclusivamente uso interno.
251 virtual void clone() throw(RuntimeException) {;}
254 const Type::_v a_type;
257 Microsecond a_timeout;
258 Microsecond a_maxTime;
261 Handler(const Handler&);
262 void do_action() throw(RuntimeException);
263 void beat(const Microsecond& now) throw() { a_maxTime = now + a_timeout; }
264 bool isTimeout(const Microsecond& now) { return a_maxTime > 0 && a_maxTime <= now; }
266 friend class Communicator;